Větvení
Bash podporuje následující formy příkazu if.
# bez else
if tst
then
commands-true
fi
# s else vetvi
if tst
then
commands-true
else
commands-false
fi
Pokud je na místě tst proměnná, je podmínka pravdivá, pokud je proměnná
neprázdná. Je-li tst příkaz, je spuštěn. Pokud je jeho návratová hodnota 0,
provede se blok commands-true. V opačném případě se ve verzi s else větví
provede commands-false. Existuje syntax i pro žebříkovou verzi konstrukce,
kde je else if nahrazeno elif
# zebrik
if tst
then
commands
elif tst
then
commands
else
commands
fi
Příkladem utility, kterou lze použít na místě tst, je grep. Pokud totiž
nalezne aspoň jednu shodu, její návratová hodnota je 0, jinak je nenulová.
Následující skript otestuje, jestli je v systému uživatel s vybraným jménem.
ouruser='franta'
if grep -q "^${ouruser}:" /etc/passwd
then
echo "uzivatel ${ouruser} existuje"
else
echo "uzivatel ${ouruser} neexistuje"
fi
Pro ověřování obecnějších podmínek lze použít utilitu test, která se používá
ve formě1
[ expression ]
Za otevírací závorkou a před uzavírací závorkou musí být mezery. Pokud test
vyhodnotí expression jako pravdivé, skončí s návratovou hodnotou 0, jinak
s hodnotou nenulovou. Na místo expression lze napsat celou řadu podmínek,
užitečná je tady manuálová stránka programu test. Existují podmínky pro celá
čísla, řetězce, testy existence, práv a jiných vlastností souborů. Ve výrazu
tst v konstrukci if lze použít logických operátorů pro spojky a (&&)
a nebo (||). V následujícím kódu jsou příklady použití několika testů.
#
# numericke porovnavani
#
# tady si je pouzito && k vytvoreni konjunkce
# n1 -ge n2 je test, jestli n1 >= n2
if [ ${a} -ge ${b} ] && [ ${a} -ge ${c} ]
then
echo "nejvetsi je a s hodnotou ${a}"
elif [ ${b} -ge ${c} ]
then
echo "nejvetsi je b s hodnotou ${b}"
else
echo "nejvetsi je c s hodnotou ${c}"
fi
#
# prace s retezci
#
x=cecil
y=josef
z=""
# proc nize expanzi promenne davame do ""?
# aby test chapal expanzi promenne jako retezec,
# ma nevhodny tvar, napriklad obsahuje vice slov, atd.
# alternativou je pouzit modernejsi [[ -n ${x} ]]
# (to potom ovsem neni program test, je to bash builtin)
# delky retezcu
if [ -n "${x}" ]
then
echo "x je neprazdny"
fi
if [ -z "${z}" ]
then
echo "z je prazdny"
fi
# rovnost
if [ "${x}" != "${y}" ]
then
echo "x a y jsou ruzne"
fi
if [ "${x}" = "${y}" ]
then
echo "x a y jsou stejne"
fi
# lexikograficke porovnani
# operator porovnani < je nutne backquotovat, jinak je bran jako presmerovani
if [ "${x}" \< "${y}" ]
then
echo "x je mensi nez y"
fi
#
# prace se soubory
#
# vypise obsah adresare, pokud existuje
# dalsi testy existence a vlastnosti souboru a adresaru jsou analogicke
addr=logs
if [ -d "${addr}" ]
then
ls ${addr}
fi
# porovnani stari souboru
if [ "${file1}" -ot "${file2}" ]
then
echo "soubor ${file1} je starsi nez ${file2}"
fi
Bash obsahuje následující rozšíření, která nemusí být podporována v jiných shellech.
-
dvojí obyčejné závorky na místě
tst(tj. výraz(( expression ))): lze použít některé aritmetické, bitové a logické operátory, kterétestneumí. -
dvojí hranaté závorky na místě
tst(tj. výraz[[ expression ]]): pro řetězcové porovnávání, obsahuje to cotest, navíc lze kontrolovat shodu s regulárním výrazem, řeší problémy s expanzí a mezerami při porovnávání řetězců a cest.
Analogií konstrukce switch z jazyka C je v Bashi case. Umožňuje porovnat
hodnotu s jinými hodnotami (jako řetězce) a v případě shody provést blok
příkazů. Syntax příkazu je následující.
case val in # val je hodnota, kterou porovnavame
pattern1) # hodnoty, se kterymi porovnavame jsou ukonceny )
cmd1 # nasleduje blok prikazu
[...]
cmdk ;; # ktery je ukoncen dvema stredniky
pattern2 | pattern3) # lze uvest vice hodnot oddelenych |, staci shoda s jednou
cmds ;;
*) # * se shoduje se vsim, je to analogie default z C
cmds ;;
esac
Je důležité si uvědomit, že na val i pattern je aplikována expanze.
Konstrukce se používá na místech, kde bychom jinak použili dlouhou if konstrukci
s mnoha elif větvemi, jak v následujícím kódu.
month=June
case ${month} in
January | March | May | July | August | October | December)
echo "${month} has 31 days" ;;
February)
echo "${month} has 28 or 29 days" ;;
April | June | September | November)
echo "${month} has 30 days" ;;
*)
echo "${month} is not a valid month"
esac
Typické použití ve skriptech je při zpracování argumentů, jak uvidíme v kapitole Vstupní argumenty.
-
Existuje program se jménem
[, který se chová jako test. ↩