====== Bash pokračování ====== Bash pokračování navazuje na [[Bash úvod]] a seznámí Vás s pokročilými technikami skriptovacího jazyka Bash. V této části se dozvíte jak používat proměnné a řídící struktury. Také budete schopni napsat své první jednoduché skripty. ====== Diakritika ====== {{.:info.png}} U programování skriptů nepoužívejte diakritiku pro názvy proměnných či funkcí. Na výstupu čeština nevadí, ale u proměnných může způsobovat problémy. ====== Způsob zápisu ====== Doporučuji používat následující způsob: \ * na jednotlivý řádek souboru = jeden řádek kódu * nad každý řádek kódu = jeden řádek komentáře, v počátcích Vám to hodně pomůže {{.:info.png}} Pokud chcete na jeden řádek napsat více příkazů, oddělte jej středníkem **;** ! ====== Sudo ====== Tento magický příkaz slouží k tomu, abyste se svým účtem mohli vykonávat úkony, které může pouze správce. Je to velká výhoda, protože kdyby tento příkaz neexistoval, mohli byste si nedopatřením smazat třeba celý systém. {{.:info.png}} Pokud při vykonávání programů narazíte na **Access Denied** nebo **Přístup odepřen** jedná se o to, že vstupujete do oblasti, kde platí jenom **Sudo**. {{.:info.png}} **Přístup odepřen** může také nastat, pokud máme např. instalujeme balík do systému a chceme jinším programem přistupovat do správy balíků. První proces si totiž zablokuje přístup pro svou činnost a dalšími programy se tam dostanete až po dokončení tohoto procesu. {{.:warning.png}} U **Sudo** platí také následující věc: Pokud nevíte co děláte nebo si nejste jistí, raději se poraďtě někde na internetu než se do toho pustíte. **Radši třikrát měřit než jednou špatně řezat**. Největší zkázu tento příkaz provede u rekurzivního mazání **rm -fr /** ! Pokud na to narazíte na internetu, tak to berte pouze jako vtípek, protože tento příkaz Vám zformátuje celý disk ! ====== Komentáře ====== V Bashi se komentáře označují znakem mřížky **#**, všechno za tímto znakem je ignorováno a slouží to především k tomu, abyste ve velkém kusu kódu věděli co dělá která část. {{.:info.png}} Doporučuji používat hodně komentářů, lépe se pak hledají chyby. ====== Příprava skriptu ====== Nyní Vám poradím jak si začít psát vlastní skript.\ * Pokud máte otevřen terminál, vytvořte si nový soubor **touch skript.sh**. Tento soubor můžete také vytvořit přes **Geany -> Uložit jako**. Koncovka **.sh** značí že se jedná o skript, nezáleží na ní, ale jedná se nám o zpřehlednění skriptu od ostatních programů pomocí koncovky. * Nyní si spusťte libovolný editor pro úpravu textu. Doporučuji používat [[Geany]] nebo [[Vim]]. * Jako první řádek každého bashové skriptu musí být následující řádek: #!/bin/bash * To pak říká interpretu jazyka Bash to, že se jedná o skript. * Nyní soubor uložte, musíme mu nastavit příznak spustitelnosti, aby se dal spouštět. * To proveďte v konzoli přes příkaz: chmod +x skript.sh * A tento skript budeme v konzoli spouštět takto: ./skript.sh * Skript by se měl spustit a ukončit bez chyb, pokud vše dopadlo jak má, skript je připraven. * Nyní budete všechny Vaše kusy kódy a příkazy psát od druhého řadku dolů. {{.:info.png}} Pokud jsou na této stránce někde kusy kódu a chybí tam hlavička **#!/bin/bash**, tak se počítá s tím, že je napsána na prvním řádku. ====== Proměnné ====== Pro uchování dat používá každý programovací jazyk proměnné a Bash není výjimkou. Proměnné v Bashi nemají svůj datový typ, proto se do nich dá ukládat cokoliv. Mají pevně definovanou syntax: \ promenna=obsahPromenne {{.:info.png}} **Deklarace** je pouze alokování proměnné a **definice** je přiřazení hodnoty do této proměnné. {{.:warning.png}} Dbejte na to, abyste používali proměnné, které mají již nějakou hodnotu ! Proměnná se skládá ze svého **názvu** a **obsahu**.\ **Název** může obsahovat písmena a čísla (**nesmí začínat číslem !**), které vystihují to, jakých bude proměnná nabývat hodnot **Obsah** může být cokoliv, textový řetězec, číslo nebo výstup programů\ Pomocí následující příkladů Vám demonstruji použití proměnných: \ # definice promenne s deklaraci promenna="ahoj svete" # promennou vypiseme pres echo echo "$promenna" # ekvivalentni vypis je take takto, vsimnete si jak ji obteka text echo "data:${promenna}:data" # promenna muze take nest obsah prikazu, používáme speciální uvozovky `` promenna2=`ls` # vypiseme promenna2 echo "$promenna2" # ukazka prepsani promenne pom="ahoj" pom="nazdar" pom="cau" # toto vypise cau, protoze je to posledni vec co se priradila do promenne pom echo "$pom" ====== Read ====== Read je příkaz pro získání dat od uživatele.\ Syntaxe: \ read PROMENNA Následující příkaz mluví za vše: \ echo -n "Zadejte svuj vek: " read vek echo "Vas vek je $vek" Do proměnné **vek** je uložen vstup od uživatele a následně vypsán. ====== If ====== If je řídící struktura, která slouží k rozhodovací podmínce **jestli něco platí či neplatí dělej**.\ Syntaxe: \ # Jednoduchý If if [ podmínka ] ; then kus kódu, který se vykoná pokud platí podmínka fi # Složený If if [ podmínka ] ; then kus kódu, který se vykoná pokud platí podmínka else kus kódu, který se vykoná pokud neplatí podmínka fi # Složený If s dalším If if [ podmínka ] ; then kus kódu, který se vykoná pokud platí podmínka elif [ podmínka2 ] ; then kus kódu, který se vykoná pokud platí podmínka2 fi Příklad: \ pom="2" if [ ! "$pom" -eq "2" ] ; then echo "Neni to cislo dva" else echo "Je to cislo dva" fi ===== Podmínky ===== Podmínky můžou být následující: \ * Řetězce: * **$promenna** délka řetězce je nenulová * **-z $promenna** délka řetězce je nulová * **"$promenna" = "$promenna2"** řetězce jsou shodné * **"$promenna" != "$promenna2"** řetězce jsou různé * Čísla: * **"$promenna" -eq "$promenna2"** čísla jsou shodná * **"$promenna" -ne "$promenna2"** čísla jsou rozdílná * **"$promenna" -le "$promenna2"** promenna1 <= promenna2 * **"$promenna" -lt "$promenna2"** promenna1 < promenna2 * **"$promenna" -ge "$promenna2"** promenna1 >= promenna2 * **"$promenna" -gt "$promenna2"** promenna1 > promenna2 * Soubory: * **"$promenna" -ef "$promenna2"** soubory sdílí stejný i-uzel * **"$promenna" -nt "$promenna2"** první soubor je novější než druhý * **"$promenna" -no "$promenna2"** první soubor je starší než druhý * **-e "$promenna"** soubor existuje * **-d "$promenna"** soubor je adresář * **-f "$promenna"** soubor je obyčejný soubor * **-L "$promenna"** soubor je symbolický odkaz * **-w "$promenna"** soubor je zapisovatelný * **-x "$promenna"** soubor je spustitelný {{.:info.png}} Pokud před výraz napíšu vykřičník **!**, celý výraz se neguje. Takže pokud mám např. **-e soubor** že testuje jestli soubor existuje, tak **! -e soubor** testuje jestli soubor neexistuje ! ===== Řetězení podmínek ===== Podmínky se dají spojovat do jedné přes operátor **&&** log. AND a **||** log. OR.\ Abych to vysvětlil matematicky, tak **&&** znamená **a současně**. Takže musí platit všechny podmínky, aby byla splněna výsledná podmínka. Místo toho **||** znamená **nebo**, takže stačí aby platila jedna z podmínek.\ Způsob zápisuje je dvojí: \ if [ -e "$pom" ] && [ -e "$pom2" ] || [ -e "$pom3" ] ; then ... Testuje jestli současně platí test existence souborů v proměnných **pom** a **pom2**. Tyto soubory musí oba existovat aby platila podmínka. Pokud jeden neexistuje, podmínka nikdy platit nebude. V tomto případě je třetí podmínka zbytečná. Druhý styl je ve výsledku stejný jako u prvního, ale způsob zápisu mně příjde elegantnější: -o znamená nebo, ||, OR -a znamená a současně, &&, AND if [ -e "$pom" -a -e "$pom2" -o -e "$pom3" ] ; then ... ====== Switch ====== Switch je takový rozsáhlejší **If**. case "$USER" in # promenna $USER root | honza ) # hodnoty: root nebo fuky echo "Ahoj Honzíku" ;; * ) # vsechno ostatni moznosti echo "Ahoj uživateli" ;; esac ====== While ====== While patří k cyklům. while [ "1" = "1" ] # cyklus vcetne podminky do # smycka po done, co se neustale opakuje, dokud plati podminka #echo echo "Dalsi slovo , konec <:exit>" echo -n "Vase volba: " read data if [ "$data" = ":exit" ] ; then break # break slouzi k vlastnimu ukonceni cyklu a pokracovani dal, v toku programu fi done # konec cyklu ====== For ====== For patří k posledním zástupcům cyklů. Používáme jej tehdy, když chceme zajistit nějaký určitý (i neurčitý) počet opakování bloku příkazů. for i in {1..5} # promenna i bude v rozsahu 1 az 5 do # 5x se provede tento blok echo "Promenna i = $i" done # Jina syntaxe = stejny efekt for (( i=1; i<=5; i++ )) do echo "Promenna i = $i" done ====== Funkce ====== Funkce se v bashi mají syntax: function nazevFunkce { # prikazy pro provedeni funkce } Funkce se poté ve skriptu volá takto: nazevFunkce ====== Závěr ====== Tohle je pouze základní přehled nástrojů bashe a jeho použití ve vlastních skriptech. Pro lepší pochopení a naučení se dělání vlastních skriptů, zkuste si podle návodu používat mnou vytvořené skripty. ====== Odkazy ====== * [[http://cs.wikibooks.org/wiki/Bash#Podm.C3.ADnky_a_testy|Odkaz]] na cs.wikibooks.org, kde je krátký návod na Bash