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 [2017/04/19 16:08] (aktuální)
admin vytvořeno
Řá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