====== 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