Skriptovanie v shelli: podmienka `if` a `case`

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 testu 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 ifom. 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 breakom, tuto jeho rolu zastupuje (eh!) dvojica bodkočiarok..

Tak ako sa if končí fi, aj case je uzatvorený svojim opakom: esacom.

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *