Viděli jsme již struktury, které řešili podmínky, ale podmínky můžeme ještě více zdokonalit. Chceme-li třeba, aby pro vykonání následujícího příkazu byly splněny dvě či více podmínek najednou, nebo aby byla splněna alespoň některá z několika podmínek, použijeme právě znaky || nebo && mezi jednotlivými podmínkami. Znaky || znamenají nebo (OR, logický součet). Pokud je alespoň jedna z podmínek oddělených těmito znaky true, je výsledek true. Naopak znaky && znamenají a (AND, logický součin). Zde musí být splněny všechny podmínky, aby výsledek byl true.
Zde je příklad použití:
#!/bin/bash
x=5
y=10
if [ "$x" -eq 5 ] && [ "$y -eq 10 ]; then
echo "Obě podmínky jsou splněny"
else
echo "Nejsou splněny obě podmínky"
fi
Podobné použití má i logický součet. Následující příklad to ilustruje:
#!/bin/bash
x=3
y=2
if [ "$x" -eq 5 ] || [ "$y -eq 2 ]; then
echo "Alespoň jedna podmínka je splněna"
else
echo "Není splněna žádná podmínka"
fi
Další využití konstrukcí AND a OR je v tzv. seznamech. Konstrukce seznamu AND umožňuje provádět sadu příkazů tím způsobem, že další příkaz je proveden jen v případě úspěšného provedení všech předchozích příkazů. Má následující syntaxi:
příkaz1 && příkaz2 && příkaz3 && ...
Začne se zleva, je proveden první příkaz a vrátí-li hodnotu true
, provede se další příkaz vpravo od něj. Tak to pokračuje, dokud některý z příkazů nevrátí hodnotu false
a tím provedení seznamu skončí. Konstrukce && testuje hodnotu předchozího příkazu.
Každý příkaz je prováděn nezávisle, takže v jednom seznamu můžeme smíchat mnoho různých příkazů, jak plyne z níže uvedeného skriptu. Seznam AND vrátí hodnotu true, když jsou všechny příkazy úspěšně provedeny, v opačném případě vrátí hodnu false.
V následujícím skriptu provedeme příkaz touch file_one
(čímž kontrolujeme existenci souboru file_one a pokud neexistuje, tak ho vytvoříme) a potom odstraníme soubor file_two. Potom pomocí seznamu AND otestujeme existenci každého ze souboru a vypíšeme nějaký text.
#!/bin/bash
touch file_one
rm -f file_two
if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo "there"
then
echo -e "in if"
else
echo -e "in else"
fi
exit 0
Výstup programu bude následující:
xconsole$ ./skript.sh
hello
in else
Jak to funguje?
Příkazy touhc a rm zajistí požadovaný stav souborů v aktuálním adresáři. Seznam && pak provede příkaz [ -f file_one ]
, který bude úspěšný, provede se příkaz echo. Ten bude také úspěšný (příkaz echo vždy vrací hodnotu true). Potom je proveden třetí test, [ -f file_two ]
, který selže, protože tento soubor neexistuje. Jelikož byl poslední příkaz neúspěšný, neprovede se poslední příkaz seznamu echo. Výsledek seznamu && je false, protože jeden z příkazů seznamu selhal, tim pádem se provede vštev else příkazu if.
Konstrukce seznamu OR umožnuje provádět skupinu příkazů, dokud jeden nevrátí hodnotu true, pak skončí. Syntaxe je následující:
příkaz1 || příkaz2 || příkaz3 || ...
Příkazy jsou prováděny zleva, jeden po druhém. Tak to pokračuje, dokud některý z příkazů nevrátí hodnotu true a tím provádění seznamu skončí.
Seznam || je podobný seznamu && s tím rozdílem, že nyní musí předchozí příkaz selhat.
Následující příklad je pouze modifikací příkladu minulého, liší se pouze v použítí seznamu OR místo seznamu AND a také nevytvoří soubor file_one. Průběh však bude díky této konstrukci jiný.
#!/bin/bash
rm -f file_one
if [ -f file_one ] || echo "hello" || echo "there"
then
echo -e "in if"
else
echo -e "in else"
fi
exit 0
Výstup programu bude následující:
xconsole$ ./skript.sh
hello
in if
Jak to funguje?
První dva řádky jen nastavují soubory pro zbytek skriptu. První příkaz [ -f file_one ]
, selže, protože daný soubor neexistuje. pak je proveden příkaz echo. Ten vrátí hodnotu true a překvapivě již nejsou žádné další příkazy seznamu || provedeny. Příkaz if bude úspěšný, protože jeden z příkazů seznamu || (echo) vrátil hodnotu true.
Výsledek obou těchto konstrukcí je výsledkem posledního provedeného příkazu.
Seznam ne vyhodnocován podobným způsobem, jakým je v jazyce C vyhodnocováno víc podmínek. K určení výsledku je proveden jen minimální počet příkazů. Příkazy, které již výsledek nemohou ovlivnit, se neprovedou. Tomu říkáme tzv. zkrácené vyhodnocování.
Zkombinování těchto dvou konstrukcí dostáváme "ráj logiků". Vyzkoušejte:
[ -f file_one ] && příkaz pro true || příkaz pro false
Bude-li test úspěšný, provede se první příkaz, v opačném případě druhý. S těmito méně obvyklými seznamy je vždy lépe trošku experimentovat.
Pokud chcete použít víc příkazů na místě, kde je povolen příkaz jeden, například v seznamu AND nebo OR, můžete si pomoci složenými závorkami a vytvořit blok příkazů. V aplikaci, kterou si ukážeme dále, se například setkáte s následujícím kódem:
get_confirm && {
grep -v "^${cdcatnum}," $tracks_file > temp_file
mv $temp_file $tracks_file
echo
add_record_tracks
}