C2110 Operační systém UNIX a základy programování 8. lekce -1C2110 Operační systém UNIX a základy programování Petr Kulhánek kulhanek@chemi.muni.cz Národní centrum pro výzkum biomolekul, Přírodovědecká fakulta Masarykova univerzita, Kamenice 5, CZ-62500 Brno 8. lekce bash – řídící struktury (podmínky, cykly) C2110 Operační systém UNIX a základy programování 8. lekce -2- Obsah ➢ Blok rozhodování • podmínky, cykly ➢ Návratová hodnota procesu • příkaz exit ➢ Příkaz test • operátory porovnání, logické operátory, zjednodušený zápis C2110 Operační systém UNIX a základy programování 8. lekce -3Blok rozhodování ano ne ? ano ne blok 1 blok 2 stav ? ano ne blok 1 změna inicializace Podmíněné vykonání bloku (podmínky) Cyklické vykonávání bloku (cykly) Typické použití bloku rozhodování počítadlo (proměnná) C2110 Operační systém UNIX a základy programování 8. lekce -4- Podmínky if prikaz1 then prikaz2 ... fi if prikaz1; then prikaz2 ... fi Kompaktní zápisy: if prikaz1 then prikaz2 ... else prikaz3 ... fi if prikaz1; then prikaz2 ... else prikaz3 ... fi Pokud prikaz1 skončí s návratovou hodnotou 0, vykoná se prikaz2. V opačném případě se vykoná prikaz3. C2110 Operační systém UNIX a základy programování 8. lekce -5Návratová hodnota procesu Končící proces může rodičovskému procesu sdělit informaci o svém průběhu pomocí návratové hodnoty. Návratová hodnota je celé číslo nabývající hodnot 0-255. Proměnné Proces: pid, ppid Proces: pid, ppid Proměnné rodičovský proces dceřiný proces návratová hodnota Návratová hodnota: 0 = vše proběhlo úspešně (pravda) > 0 = došlo k chybě, vrácená hodnota pak zpravidla identifikuje chybu (nepravda) Návratovou hodnotu posledně provedeného příkazu lze zjistit pomocí proměnné ?. C2110 Operační systém UNIX a základy programování 8. lekce -6Návratová hodnota, příklady $ mkdir test $ echo $? 0 $ mkdir test mkdir: cannot create directory `test': File exists $ echo $? 1 $ expr 4 + 1 5 $ echo $? 0 $ expr a + 1 expr: non-integer argument $ echo $? 1 C2110 Operační systém UNIX a základy programování 8. lekce -7Příkaz test, operátory porovnávání Porovnávání celých čísel: test cislo1 operator cislo2 Operátor : -eq rovná se (equal) -ne nerovná se (not equal) -lt menší než (less than) -le menší než nebo rovno (less or equal) -gt větší než (greater than) -ge větší než nebo rovno (greater or equal) Alternativní zápis: [[ cislo1 operator cislo2 ]] [ Příkaz test slouží k porovnávání hodnot a testovaní typů souborů a adresářů (man bash, man test). V případě, že je test splněn, je návratová hodnota příkazu nastavena na 0 (pravda). musí být mezery C2110 Operační systém UNIX a základy programování 8. lekce -8Příkaz test, logické operátory Logické operátory: || logické nebo && logické ano ! negace Příklady: [[ (cislo1 operator cislo2) || (cislo3 operator cislo4) ]] [[ (cislo1 operator cislo2) ]] || [[ (cislo3 operator cislo4) ]] • Pomocí logických operátorů, lze vytvářet složitější podmínky. • Pokud neznáme prioritu operátorů nebo si nejsme jisti, tak používáme kulaté závorky. • Bash používá líné vyhodnocování podmínek, které spočívá ve vyhodnocování pouze té části složené logické podmínky, kterou je nutné vyhodnotit pro zjištění výsledné logické hodnoty. stejný výsledek, jiný způsob interpretace! nedoporučuji používat C2110 Operační systém UNIX a základy programování 8. lekce -9Líné vyhodnocování [[ výraz1 || výraz2 ]] <-> [[ vyraz1 ]] || [[ vyraz2 ]] Pokud je první výraz pravda (T), tak je výsledek vždy pravda. Proto se výraz2 vyhodnocuje jen tehdy, pokud není první výraz pravda. [[ výraz1 && výraz2 ]] <-> [[ vyraz1 ]] && [[ vyraz2 ]] Pokud je první výraz nepravda (F), tak je výsledek vždy nepravda. Proto se výraz2 vyhodnocuje jen tehdy, pokud je první výraz pravda. F || F = F F || T = T T || F = T T || T = T F && F = F F && T = F T && F = F T && T = T Trik: mkdir adresar || exit 1 pokud příkaz mkdir selže (F), zavolá se příkaz exit a skript se ukončí C2110 Operační systém UNIX a základy programování 8. lekce -10Praktický příklad - podmínka ok? ne ano vytvoř adresář K chyba mkdir adresar 2> /dev/null if [[ $? –ne 0 ]]; then echo "Nemohu vytvorit adresar!" exit 1 fi if ! mkdir adresar 2> /dev/null; then echo "Nemohu vytvorit adresar!" exit 1 fi funkčně identické zápisy mkdir adresar 2> /dev/null if test $? –ne 0; then echo "Nemohu vytvorit adresar!" exit 1 fi C2110 Operační systém UNIX a základy programování 8. lekce -11Cyklus pomocí while/until while prikaz1 do prikaz2 ... done while prikaz1; do prikaz2 ... done Kompaktní zápis: cyklus probíhá zatímco prikaz1 vrací v návratové hodnotě 0 (bez chyby) Cyklus (smyčka) je řídicí struktura, která opakovaně provádí posloupnost příkazů. Opakování i ukončení cyklu je řízeno podmínkou. until prikaz1; do prikaz2 ... done cyklus probíhá dokud prikaz1 nevrátí v návratové hodnotě 0 C2110 Operační systém UNIX a základy programování 8. lekce -12Cyklus pomocí while/until ... stav ? ano ne blok 1 změna inicializace stav ? ano ne blok 1 změna inicializace vyhodnocení podmínky na konci cyklu Tento algoritmus nemá přímou podporu v řídích strukturách jazyka bash, jeho přepis je možný, ale za cenu horší čitelnosti výsledného kódu. snadná transformace komplikovaná implementace C2110 Operační systém UNIX a základy programování 8. lekce -13Praktický příklad - cyklus I < N ano ne I = I + 1 N=10 I=0 writestr "X" počítadlo (proměnná) N=10 I=0 while test "$I" –lt "$N"; do echo "X" ((I = I + 1)) done N=10 I=0 while [[ "$I" –lt "$N" ]]; do echo "X" ((I = I + 1)) done N=10 I=0 while [[ I –lt N ]]; do echo "X" ((I = I + 1)) done nutno použít $ volitelné $, pokud je použit blok [[ ]] nebo (( )) C2110 Operační systém UNIX a základy programování 8. lekce -14Složitější konstrukce - vnořování Jazyk bash nemá návěstí a příkaz goto, či jeho obdobu. Komplexnějších konstrukcí lze tedy dosáhnout jen zanořováním cyklů a podmínek vzájemně do sebe. Úroveň zanoření není omezena. podminka cyklus Při návrhu algoritmu/skriptu se však snažíme o zamezení zbytečného vnořovaní (převážně z důvodu snadnější orientace ve skriptu). ! podminka cyklus exit Vhodnější uspořádání např. pro testovaní vstupních dat od uživatelů. C2110 Operační systém UNIX a základy programování 8. lekce -15Příkaz exit Příkaz exit slouží k ukončení běhu skriptu nebo interaktivního sezení. Nepovinným argumentem příkazu je návratová hodnota. #!/bin/bash if test "$1" –lt 0; then echo "Cislo je mensi nez nula!" exit 1 fi echo "Cislo je vetsi nebo rovno nule." exit 0 $ ./muj_skript 5 Cislo je vetsi nebo rovno nule. $ echo $? 0 $ ./muj_skript -10 Cislo je mensi nez nula! $ echo $? 1 C2110 Operační systém UNIX a základy programování 8. lekce -16Vnořování cyklů - příklad počítadlo vnějšího cyklu může ovlivňovat chování vnitřního cyklu N=10 I=0 while [[ I –lt N ]]; do J=0 while [[ J –lt I ]]; do echo –n "X" ((J = J + 1)) done echo "" ((I = I + 1)) done U zanořených konstrukcí dbáme na odsazovaní textových bloků, které zvyšuje přehlednost a čitelnost kódu. V textových editorech je integrována podpora, která odsazovaní usnadňuje, např. v editoru gedit, lze odsazení označeného textového bloku dosáhnout klávesou TAB či Shift+TAB. C2110 Operační systém UNIX a základy programování 8. lekce -17Cvičení I 1. Napište skripty v jazyce bash pro následující úlohy. Rozměr vykreslovaného obrazce nechť uživatel zadá interaktivně po spuštění skriptu. C2110 Operační systém UNIX a základy programování 8. lekce -18Úkol 1 Do terminálu vytiskněte čtverec se znaků X. Délku strany čtverce zadá uživatel. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X To, že se nejedná vzhledově o čtverec, ignorujte. Počet znaků X na řádku a počet řádků však musí být stejný. C2110 Operační systém UNIX a základy programování 8. lekce -19Úkol 2 Do terminálu vytiskněte pravoúhlý trojúhelník se znaků X, tak aby jedna odvěsna byla umístěna nahoře a druhá na levé straně. Délku odvěsny zadá uživatel. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X C2110 Operační systém UNIX a základy programování 8. lekce -20Úkol 3 Do terminálu vytiskněte pravoúhlý trojúhelník se znaků X, tak aby jedna odvěsna byla umístěna dole a druhá na levé straně. Délku odvěsny zadá uživatel. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X C2110 Operační systém UNIX a základy programování 8. lekce -21Úkol 4 Do terminálu vytiskněte obrys čtverce se znaků X. Délku strany čtverce zadá uživatel. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X To, že se nejedná vzhledově o čtverec, ignorujte. Počet znaků X na řádku a počet řádků však musí být stejný. C2110 Operační systém UNIX a základy programování 8. lekce -22Úkol 5 Do terminálu vytiskněte obrys čtverce a jeho uhlopříčky se znaků X. Délku strany čtverce zadá uživatel. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X To, že se nejedná vzhledově o čtverec, ignorujte. Počet znaků X na řádku a počet řádků však musí být stejný. C2110 Operační systém UNIX a základy programování 8. lekce -23Domácí úkoly C2110 Operační systém UNIX a základy programování 8. lekce -24Domácí úkoly Pokyny: 1. Uvedené úkoly jsou pro pokročilé studenty. 2. Cílem úkolů je rozvinout vaši schopnost řešit problémy, který jsou zdánlivě neřešitelné z pohledu možností a zdrojů, které máte k dispozici. V případě jazyka bash se jedná převážně o možnost pracovat pouze s celočíselnou aritmetikou a omezený způsob vykreslování na terminál. Zadání: 1. Vykreslete kruh z písmen "X". Poloměr kruhu zadá uživatel po spuštění skriptu. 2. Vykreslete kružnici z písmen "X". Poloměr kružnice zadá uživatel jako první argument skriptu.