Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

vyuka:podminky_a_cykly [2023/11/15 20:54] (aktuální)
Řádek 1: Řádek 1:
 +===== Ří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í:
 +<code bash>
 +# 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
 +</code>
 +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šší:
 +<code bash>
 +if [příkaz podmínky]
 +then
 +  [příkazy k vykonání]
 +fi
 +</code>
 +
 +Použití ''else'' = jinak:
 +<code bash>
 +if [příkaz podmínky]
 +then
 +  [udělej cosi]
 +else
 +  [udělej něco jiného]
 +fi  
 +</code>
 +Použití ''elif'' - další podmínky:
 +<code bash>
 +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         
 +</code>
 +
 +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 ===
 +<code>
 +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
 +</code>
 +
 +=== Ú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:
 +<code bash>
 +expr 5 + 5
 +expr 3 \* 2 
 +</code>
 +(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:
 +<code bash>
 +expr 5 \* 3 + 8
 +</code>
 +
 +Lze použít (odescapované) závorky - pro změnu priority operací:
 +<code bash>
 +expr 5 \* \( 3 + 2 \)
 +#Vypíše 25
 +
 +expr 5 \* 3 + 2
 +#Vypíše 17
 +</code>
 +
 +''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!
 +<code bash>
 +#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
 +</code>
 +
 +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Í''
 +<code bash>
 +seq 10 -2 1
 +#vypíše 10 8 6 4 2
 +</code>
 +
 +----
 +====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:
 +<code bash>
 +#!/bin/sh
 +echo "Zadej prvni cislo"
 +read a 
 +echo "Zadej druhe cislo"
 +read b
 +echo "Secteno je to `expr $a + $b`"
 +</code>
 +----
 +===for===  
 +<code bash>
 +for promenna in seznam
 +do
 +  prikaz
 +done   
 +</code>
 +Přičemž ''seznam'' je jakkoliv dlouhá posloupnost řetězců (oddělených mezerou).
 +Mohou to být čísla:
 +<code bash>
 +for a in 1 2 3 4
 +do
 + expr $a * $a
 +done
 +</code>
 +
 +Stejně tak to ale mohou být i slova:
 +<code bash>
 +for a in stul zidle lampa skrin
 +do
 + echo $a je kus nabytku
 +done
 +</code>
 +
 +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:
 +<code>
 +for a in `seq 1 100`
 + do
 + expr $a \* 2
 +done
 +
 +----
 +===while===    
 +<code bash>
 +while podminka
 +do
 +  prikaz
 +done  
 +</code>
 +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:
 +<code bash>
 +a=0
 +while [ $a -le 100 ]
 + do
 + echo $a
 + a=`expr a + 1`
 +done
 +</code>
 +
 +Nebo na čtení ze vstupu pomocí příkazu ''read''
 +<code bash>
 +while read radek
 + do 
 + echo "$radek"
 +done
 +
 +Nebo na čtení ze souboru:
 +<code bash>
 +while read radek
 + do
 + echo "$radek"
 + done < soubor
 +</code>
 +(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 
 +<code bash>
 +./secti.sh 1 4 5 12
 +22
 +</code>
 +
 +=== Úloha ===
 +Script, který očísluje řádky vstupu / souboru.
 +Tj ze souboru
 +<code>
 +ahoj
 +svete
 +jak se mas?
 +</code>
 +udělá:
 +<code>
 +1 ahoj
 +2 svete
 +3 jak se mas?
 +</code>
Nahoru