C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -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 PS/2021 Prezenční forma výuky: Rev4 7. lekce / modul 1 C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -2- Rozhodování C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -3I. Ná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 úspěš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í 7. lekce / modul 1 -4Ná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í 7. lekce / modul 1 -5Pří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í 7. lekce / modul 1 -6II. Příkaz test Binární operátory (vyžadující dva argumenty): test argument1 operator argument2 Preferovaný „alternativní“ zápis: [[ argument1 operator argument2 ]] Unární operátory (vyžadující jeden argumenty): test operator argument1 Preferovaný „alternativní“ zápis: [[ operator argument1 ]] 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 musí být mezery musí být mezery musí být mezery C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -7Příkaz test, celá čísla Další informace: man bash, man test Porovnávání celých čísel: [[ 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) != nerovná se == rovná se < menší <= menší nebo rovno > větší >= větší nebo rovno Příklady: [[ I -eq 5 ]] [[ J -le K ]] je hodnota proměnné I rovna 5? je hodnota proměnné K menší nebo rovna hodnotě proměnné K? při použití [[…]] a operátorů porovnávající celá čísla není nutné použít operátor $ pro získaní hodnoty proměnné C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -8Příkaz test, řetězce Porovnávání řetězců test retezec1 operator retezec2 [[ retezec1 operator retezec2 ]] Operátor : == řetězce jsou identické (lze použít i =) != řetězce se liší Příklady: [[ $A == "ahoj" ]] [[ $J != $K ]] obsahuje proměnná A řetězec "ahoj"? obsahuje proměnná K různý řetězec než proměnná K? Pro získání hodnoty proměnné je NUTNÉ použít operátor $. C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -9Příkaz test, řetězce II Testovaní řetězců test operator retezec1 [[ operator retezec1 ]] Operátor : -n testuje zda-li řetězec nemá nulovou délku -z testuje zda-li řetězec má nulovou délku -f testuje zda-li je řetězec název existujícího souboru -d testuje zda-li je řetězec název existujícího adresáře Příklady: [[ -n $I ]] [[ -f $K ]] obsahuje proměnná I hodnotu? obsahuje proměnná K název existujícího souboru? Pro získání hodnoty proměnné je NUTNÉ použít operátor $. C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -10Manipulace s názvy souborů/adresářů Příkazy: basename - vytiskne název souboru, eventuálně odstraní příponu z názvu dirname - vytiskne název adresáře Příkazy pracují s prostým textem, názvy nemusí odkazovat na existující soubory. Příklady: basename pokus.txt .txt basename adresar/pokus.txt NAME=`basename "$FILE" .doc` dirname adresar/pokus.txt DIR=`dirname "$FILE"` vypíše "pokus" vypíše "pokus.txt" do proměnné NAME vloží název souboru bez přípony .doc z proměnné FILE vypíše "adresar" do proměnné DIR vloží název adresáře z proměnné FILE C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -11Pří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í 7. lekce / modul 1 -12Lí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í 7. lekce / modul 1 -13Příkaz test, příklady [[ (I -ge 5) && (I –le 10) ]] Je hodnota proměnné I v intervalu <5;10>? [[ (I -lt 5)||(I –gt 10) ]] nebo [[ !((I -ge 5)&&(I –le 10)) ]] Je hodnota proměnné I mimo interval <5;10>? [[ I –ne 0 ]] Je hodnota proměnné I ruzná od nuly? [[ $A == "test" ]] Obsahuje proměnná A řetězec "test"? [[ $A != "test" ]] Obsahuje proměnná A jiný řetězec než "test"? [[ -z $A ]] Obsahuje proměnná A prázdný řetězec? [[ -f $NAME ]] Existuje soubor, jehož jméno je v proměnné NAME? [[ ! (-d $NAME) ]] Neexistuje adresář, jehož jméno je v proměnné NAME? C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -14[[…]], test, […] [[ (I -ge 5) && (I -le 10) ]] test $I -ge 5 && test $I -le 10 [ ($I -ge 5) && ($I -le 10) ] [[ -f $A ]] test -f "$A" [ -f "$A" ] preferovaný zápis preferovaný zápis vyžaduje komplikovanější zápis, použití operátoru $ a eventuálně uvozovek vyžaduje komplikovanější zápis, použití operátoru $ a eventuálně uvozovek Podrobnosti: • man test • man bash (CONDITIONAL EXPRESSIONS) C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -15- Podmínky ? ano ne blok 1 blok 2 Podmíněné vykonání bloku C2110 Operační systém UNIX a základy programování 7. lekce / modul 1 -16- 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í 7. lekce / modul 1 -17Praktický 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í 7. lekce / modul 1 -18Cvičení I 1. Vyzkoušejte si příklady uvedené na předchozí straně. Existenci adresáře monitorujte příkazem ls a měňte příkazy mkdir a rmdir. 2. Napište skript, který vypíše výsledek podílu dvou čísel. Hodnoty uživatel zadá interaktivně po spuštění skriptu. Skript ošetří možné dělení nulou. 3. Napište skript, který se dotáže na jméno souboru. Skript vypíše chybové oznámení, pokud soubor neexistuje. V opačném případě jej vypíše do standardního výstupu.