PředchozíNahoruDalšíObsah

10. AND & OR

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
}

PředchozíNahoruDalšíObsah

11. dubna 2001 18:46