Modul 4 — Skriptování a automatizace

16. Bash skriptování od základů (proměnné, podmínky, cykly)

Základní stavební prvky Bash skriptů — proměnné, argumenty, podmínky a cykly — na kterých stojí většina automatizačních skriptů v provozu.

Odhadovaná délka studia: 55 minut · Stav: nehotovo

Technologie: Bash

Úvod a kontext

V předchozích lekcích jsme používali jednotlivé shellové příkazy
(ls, grep, git...) ručně, jeden po druhém. Skutečná síla shellu
se ale projeví, když sekvenci příkazů uložíte do souboru a necháte ji
spouštět opakovaně, s podmínkami a cykly — to je Bash skript. Bash
(Bourne Again SHell) je nejrozšířenější shell na linuxových serverech
a jeho skripty jsou základním nástrojem DevOps automatizace: instalační
skripty, deploy skripty, healthchecky, cron úlohy — všude tam, kde
stačí jednoduchá logika a není potřeba plnohodnotný programovací
jazyk jako Python.

Teorie

Shebang a spustitelnost

Skript začíná tzv. shebang řádkem, který systému říká, jakým
interpretem se má soubor spustit:

#!/bin/bash

Aby šel skript spustit přímo (./skript.sh), potřebuje právo ke
spuštění (chmod +x skript.sh). Alternativně lze skript spustit i bez
tohoto práva příkazem bash skript.sh.

Proměnné

Proměnné se nastavují bez mezer kolem = a čtou s dolarem:

jmeno="Petr"
echo "Ahoj, $jmeno"

Rozdíl mezi uvozovkami: v dvojitých uvozovkách ("...") se
proměnné a příkazy interpretují (tzv. interpolace), v jednoduchých
('...') se bere text doslovně. To je častý zdroj chyb — '$jmeno'
vypíše doslova $jmeno, ne obsah proměnné.

Argumenty skriptu

Skript má přístup ke svým argumentům přes speciální proměnné:

  • $0 — název samotného skriptu.
  • $1, $2, ... — jednotlivé argumenty podle pořadí.
  • $# — počet argumentů.
  • $@ — všechny argumenty jako seznam.

Substituce příkazů

Výstup příkazu lze uložit do proměnné pomocí $(...):

datum=$(date +%Y-%m-%d)

Podmínky

Bash používá if/then/elif/else/fi. Testovací výraz se obvykle
píše v hranatých závorkách (interně volá příkaz test), přičemž mezery
kolem závorek jsou povinné
:

if [ "$prostredi" = "produkce" ]; then
    echo "Pozor, pracujete v produkci!"
elif [ "$prostredi" = "test" ]; then
    echo "Testovací prostředí."
else
    echo "Neznámé prostředí."
fi

Časté testovací operátory: -eq/-ne/-lt/-gt pro čísla, =/!=
pro řetězce, -f soubor (existuje a je to soubor), -d adresar
(existuje a je to adresář), -z retezec (je prázdný), -z "$x"
(proměnná je nenastavená nebo prázdná).

Cykly

for cyklus pro iteraci přes seznam hodnot nebo soubory:

for soubor in *.log; do
    echo "Zpracovávám $soubor"
done

while cyklus opakuje blok, dokud je podmínka pravdivá — typický pro
čekání na nějaký stav nebo čtení řádků ze souboru:

while [ ! -f /tmp/hotovo ]; do
    echo "Čekám na dokončení..."
    sleep 2
done

Návratové kódy a exit

Každý příkaz v Linuxu vrací návratový kód (exit status): 0 znamená
úspěch, cokoliv jiné (1–255) znamená chybu. Bash tento kód zpřístupňuje
v proměnné $? hned po spuštění příkazu. Skript sám může vrátit svůj
kód příkazem exit N — to je důležité, protože ostatní nástroje
(cron, CI pipeline, jiné skripty volající ten váš) se podle
návratového kódu rozhodují, jestli operace uspěla.

Praktický příklad

Skript, který zkontroluje, zda běží daná systemd služba, a pokud ne,
pokusí se ji restartovat — typický jednoduchý "healthcheck" skript:

#!/bin/bash
# kontrola-sluzby.sh — zkontroluje a případně restartuje systemd službu.

SLUZBA="$1"

if [ -z "$SLUZBA" ]; then
    echo "Použití: $0 <název-služby>"
    exit 1
fi

if systemctl is-active --quiet "$SLUZBA"; then
    echo "Služba $SLUZBA běží v pořádku."
    exit 0
else
    echo "Služba $SLUZBA neběží, pokouším se restartovat..."
    systemctl restart "$SLUZBA"
    sleep 2
    if systemctl is-active --quiet "$SLUZBA"; then
        echo "Restart úspěšný."
        exit 0
    else
        echo "Restart selhal!"
        exit 1
    fi
fi

Spuštění a ověření chování:

$ chmod +x kontrola-sluzby.sh
$ ./kontrola-sluzby.sh nginx
Služba nginx běží v pořádku.
$ echo $?
0

Skript procházející cyklem přes seznam serverů a testující jejich
dostupnost pomocí ping:

#!/bin/bash
servery=("web1.example.com" "web2.example.com" "db1.example.com")

for server in "${servery[@]}"; do
    if ping -c 1 -W 2 "$server" > /dev/null 2>&1; then
        echo "$server: OK"
    else
        echo "$server: NEDOSTUPNÝ"
    fi
done

Poznámka k "${servery[@]}" — jde o pole (array) v Bashi; uvozovky
kolem expanze jsou důležité, aby se položky obsahující mezery
nerozdělily nechtěně na víc slov.

Shrnutí

Bash skript je sekvence shellových příkazů uložená v souboru, se
shebang řádkem #!/bin/bash a právem ke spuštění. Proměnné se čtou
s $, argumenty skriptu jsou dostupné jako $1, $2, $#,
podmínky se zapisují přes if [ ... ]; then, cykly přes for/while
a každý příkaz i skript samotný komunikuje úspěch/neúspěch přes
návratový kód ($?, exit N). Tyto základní prvky stačí na velkou
část jednoduché provozní automatizace — healthchecky, monitorovací
skripty, jednoduché deploy kroky.

Kontrolní otázky

  1. Jaký je rozdíl mezi "$promenna" v dvojitých a '$promenna' v
    jednoduchých uvozovkách?
  2. K čemu slouží proměnné $1, $# a $@ uvnitř skriptu?
  3. Co znamená návratový kód 0 a proč na něm závisí chování nástrojů
    jako cron nebo CI pipeline?
  4. Napište krátký Bash skript, který přijme jako argument cestu k
    adresáři a vypíše, kolik souborů s příponou .log v něm existuje
    (nápověda: for cyklus přes *.log a čítač).

Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.