===== Ří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 [[http://en.wikipedia.org/wiki/Test_%28Unix%29|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 [[vyuka:metaznaky_shellu|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 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=== 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: 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?