Podmienka if
Podmienky v shellovom skriptovaní stoja na pleciach návratových kódov. Každý program má možnosť vrátiť do operačného systému číselný kód, tzv. exit code, pričom nula znamená “zbehol som v poriadku”.
Ak ste niekedy programovali v C, tak viete, že tamojšia funkcia main()
vracia int
, čo je presne hodnota pre exit code.
Exit code, príkazy true
a false
Exit code posledného zbehnutého príkazu môžete zistiť z premennej $?
. Ukážme si to na veselom príkaze true
:
true
Ten nevypíše nič, ale zistíme jeho návratový kód:
echo $?
Výsledkom je
0
Takisto existuje jeho opak: false
, ktorý tiež nevypisuje nič, ale vždy vráti exit code 1.
Príkaz test
Poďme však na zmysluplnejšie príkazy. Chcete zistiť, či používate distribúciu Debian? Ak áno, mal by existovať súbor /etc/debian_version
.
Jedna z možností je použiť cat
:
novotnyr@itat:~$ cat /etc/debian_version; echo $?
cat: /etc/debian_version: No such file or directory
1
Všimnite si exit code 1, čo je všeobecné zlyhanie. Ako “bonus” dostanete hlášku o neexistujúcom súbore.
Alternatívne je možné použiť ls
, kde dostanete pre zmenu exit code 2 (a takisto hlášku).
V skripte to však môže prekážať. Samozrejme, mohli by sme presmerovať chybový výstup do /dev/null
, ale načo, keď existuje jednoduchší spôsob?
test -f /etc/debian_version; echo $?
Spustili sme príkaz test
s parametrom -f
, kde testujeme, či uvedený súbor existuje a či je to regulárny súbor (teda nie adresár). Žiadna chybová hláška, len jednoduchý exit code 1. Výhodou test
u je široká plejáda možností: chcete testovať, či súbor je adresárom? Symbolickým linkom? Či je novší než iný súbor? Nebodaj chcete kombinovať viacero podmienok? ? Pustite si man test
a obdivujte.
Príkaz test
ide ruka v ruke s if
om. Ten totiž zoberie exit code spusteného príkazu a ak zistí, že je nulový, prejde do pozitívnej vetvy:
if test -f /etc/debian_version
then
echo "Pouzivate Debian"
fi
Všimnite si then
na samostatnom riadku a fi
ako koniec podmienky (áno, je to prevrátené if
).
Samozrejme, funguje aj else
:
if test -f /etc/debian_version
then
echo "Pouzivate Debian."
else
echo "Pouzivate neznamu distribuciu."
fi
Príkaz [
Existuje aj kratšia syntax pre podmienky využívajúca hranaté zátvorky:
if [ -f /etc/debian_version ]
then
echo "Pouzivate Debian"
fi
Pozor na medzery! Okolo ľavej hranatej zátvorky musia byť medzery a nesmie chýbať pravá hranatá zátvorka!
Využíva sa totiž megatrik: existuje totiž program s poetickým názvom [
(áno, hranatá zátvorka), ktorý sa napr. v Debiane nachádza v /usr/bin/[
. Ten má identickú funkcionalitu ako test
— dokonca v niektorých variantoch shellu je to len alternatívny názov (alias). (Ak sa čudujete podivnému názvu: POSIXOvé konvencie tvrdo zakazujú len lomku a znak NULL
;-))
V skutočnosti sa teda volá príkaz [
s troma parametrami: -f
, /etc/debian_version
a ukončovacia (a estetická) ]
.
Klauzula elif
Ak náhodou potrebujete else if
, volá sa elif
:
#!/bin/bash
if [ -f /etc/redhat-release ]
then
DISTRO="RedHat"
elif [ -f /etc/SuSE-release ]
then
DISTRO="SuSE"
elif [ -f /etc/debian_version ]
then
DISTRO="RedHat"
else
DISTRO="nezname"
fi
echo "Vasa distribucia: $DISTRO"
Podmienka case
Alternatívou k divoko rozvetvenému if
je case
. Každá vetva je charakterizovaná vzorom (pattern) v duchu podobnom regulárnym výrazom. Ak sa shellové slovo zhoduje so vzorom, vykoná sa príslušná vetva. Nasledovný miniskript zistí hodnotu prvého argumentu z príkazového riadka a na základe toho vypíše vhodný text.
case "$1" in
start)
echo "Startujem..."
;;
stop)
echo "Zastavujem..."
;;
*)
echo "Pouzitie: $0 start|stop"
esac
Všimnite si vzory: každý je ukončený zátvorkou )
. Vzory start
a stop
sú jednoduché: prakticky sa overí rovnosť reťazcov. Vzor *
sa zhoduje s ľubovoľným počtom znakov, čo vyrieši implicitnú situáciu (default
), čiže tú, v ktorej sa nezhodol ani jeden predošlý vzor.
Ďalej je pozoruhodné ukončenie vetiev: v C
a Jave
by sa každá vetva končila break
om, tuto jeho rolu zastupuje (eh!) dvojica bodkočiarok..
Tak ako sa if
končí fi
, aj case
je uzatvorený svojim opakom: esac
om.