Obsah
Řídící konstrukce v shellu
Dnes si ukážeme podmínku if
, a cykly for
a while
. Pokud jste již programovali v procedurálním jazyce, jistě vám tyto konstrukce nebudou neznámé. Jen je třeba si zvyknout na trošku odlišnou syntaxi.
Průběžně si také ukážeme několik pomocných příkazů - test
, expr
, seq
test
Příkaz, jehož aliasem je hranatá závorka - [
(pokud je test použitý takhle, musí mít jako poslední parametr opačnou hranatou závorku ]
).
Vrací true / false, ovšem pouze jako návratový kód. Má smysl ho tedy používat právě v podmínkách.
Nejdůležitější použití:
# FUNKCE SE SOUBORY # Existuje soubor file? test -e file # Lze do souboru file zapisovat? test -w file # FUNKCE S ŘETĚZCI # Je proměnná $A neprázdná? test -n "$A" # Je proměnná $A prázdná? test -z "$A" # FUNKCE S ČÍSLY # Je $A stejná jako (equals) $B ? test $A -eq $B # Je $A menší než (lesser then) $B? test $A -lt $B # Je $A menší nebo rovna (lesser or equal then) $B? test $A -le $B # Je $A větší než (greater then) $B? test $A -gt $B # Je $A větší nebo rovna (greater or equal then) $B? test $A -ge $B
Více ve Wikipedii(en)
Použití v podmínce if:
if
Za if
se píše příkaz, vracející návratový kód 0(true)/jiný (false). Může to být příkaz test, ale ne nutně - vlastně většina příkazů či programů onen návratový kód vrací dle kontextu (například cp … povedlo se či nepovedlo kopírování?).
Nejjednodušší:
if [příkaz podmínky] then [příkazy k vykonání] fi
Použití else
= jinak:
if [příkaz podmínky] then [udělej cosi] else [udělej něco jiného] fi
Použití elif
- další podmínky:
read num if [ $num -eq 5 ] then echo "Cislo je vetsi nez pet" elif [ $num -lt 5 ] echo "Cislo je mensi nez pet" else echo "Jina moznost" fi
Pozor:
- Tam kde jsou odřádkování skutečně musí být odřádkování - nebo středník ;
- nezapomeňte na
fi
na konci.
Příklady
if test $A -eq $B then echo "A je rovno B!" else echo "A se nerovná B." fi if [ $A -lt $B ] then echo "A je menší než B" elif [ $A -gt $B ] echo "A je větší než B" elif [ $A -eq $B ] echo "A je stejné jako B" else # Možná to nejsou čísla echo "Err" fi
Úloha:
Jak ve scriptu zkontrolovat, zda je parametr $1 číselný?
expr
expr
je další užitečný příkaz. Slouží k aritmetice - k počítání s celými čísly.
Například tedy:
expr 5 + 5 expr 3 \* 2
(Nezapomeňme, že hvězdička je metaznak shellu)
Každý člen výrazu musí být samostatný parametr - tedy oddělený od ostatních mezerou. Vypočítat pomocí expr
výraz 5*3+8 lze tedy:
expr 5 \* 3 + 8
Lze použít (odescapované) závorky - pro změnu priority operací:
expr 5 \* \( 3 + 2 \) #Vypíše 25 expr 5 \* 3 + 2 #Vypíše 17
expr
lze samozřejmě jednodušše použít i k počítání s proměnnými. Musí být ale skutečně obsahovat čísla!
#sčítání parametrů expr $1 + $2 #Zvýšení hodnoty proměnné a=`expr $a + 1` ---- ==== seq ==== Příkaz ''seq'' vypisuje číselnou řadu. Typicky se používá se dvěma parametry - prvním číslem a posledním - například <code bash> seq 1 5 #vypíše 1 2 3 4 5
Lze ale i změnit krok (navyšovat o deset a ne o jednu, nebo dokonce záporně) - se třemi parametry jako
seq PRVNÍ KROK POSLEDNÍ
seq 10 -2 1 #vypíše 10 8 6 4 2
read
read r
přečte jednu řádku ze vstupu a uloží ji do proměnné r.
Dá se použít například v interaktivní kalkulačce:
#!/bin/sh echo "Zadej prvni cislo" read a echo "Zadej druhe cislo" read b echo "Secteno je to `expr $a + $b`"
for
for promenna in seznam do prikaz done
Přičemž seznam
je jakkoliv dlouhá posloupnost řetězců (oddělených mezerou).
Mohou to být čísla:
for a in 1 2 3 4 do expr $a * $a done
Stejně tak to ale mohou být i slova:
for a in stul zidle lampa skrin do echo $a je kus nabytku done
Je tedy vidět, na co se nám hodí příkaz seq
?
Cyklus „pro všechna čísla od 1 do 100 vypiš jejich dvojnásobky“ napíšeme jako:
for a in `seq 1 100` do expr $a \* 2 done ---- ===while=== <code bash> while podminka do prikaz done
Cyklus while se opakuje, dokud je podmínka splněna. Je tedy potřeba zajistit, aby někdy splněna byla - jinak cyklus nikdy neskončí.
Podmínka ve while
je to samé, jako podmínka v if
. Můžeme tak třeba jednoduše nahradit for cyklus:
a=0 while [ $a -le 100 ] do echo $a a=`expr a + 1` done
Nebo na čtení ze vstupu pomocí příkazu read
while read radek do echo "$radek" done Nebo na čtení ze souboru: <code bash> while read radek do echo "$radek" done < soubor
(pozor na soubory které nekončí znakem nové řádky!)
Úloha:
Vytvořte script secti.sh, který sečte všechny svoje parametry (které jsou číselné). Tj. například
./secti.sh 1 4 5 12 22
Úloha
Script, který očísluje řádky vstupu / souboru. Tj ze souboru
ahoj svete jak se mas?
udělá:
1 ahoj 2 svete 3 jak se mas?