Opakující se příkazy se používají k tomu, aby program opakovaně provedl příkaz. Provedený příkaz se nazývá tělo smyčky.
Smyčky se spouštějí, dokud hodnota řídicího výrazu není 0. Řídicím výrazem může být jakýkoli skalární datový typ.
Jazyk shellu také poskytuje několik iteračních nebo cyklických příkazů. V tomto článku si na několika příkladech zopakujme cyklické příkazy, které bash poskytuje.
Bash podporuje následující tři typy cyklických příkazů
- Pro smyčku
- Během smyčky
- Až do smyčky
Tento článek je součástí probíhající série Bash Tutorial.
Smyčky lze vnořovat. Stejně jako jakýkoli jiný programovací jazyk podporuje bash také příkaz break pro ukončení aktuální smyčky a příkaz continue pro obnovení další iterace příkazu smyčky.
Bash For Loop – první metoda
Smyčky For se obvykle používají, když je znám počet iterací před vstupem do bashové smyčky. Bash podporuje dva druhy smyček for. První forma bash for smyčky je:
for varname in list do commands ##Body of the loop done
Ve výše uvedené syntaxi:
- pro, in, do a done jsou klíčová slova
- Seznam je jakýkoli seznam, který obsahuje seznam položek
- název_varianta je libovolný název proměnné Bash.
V tomto formuláři příkaz for provede příkaz uzavřený v těle jednou pro každou položku v seznamu. Aktuální položka ze seznamu bude uložena do proměnné „varname“ při každém průchodu smyčkou. Tento název proměnné lze zpracovat v těle smyčky. Tento seznam může být proměnná, která obsahuje několik slov oddělených mezerami. Pokud v příkazu for chybí seznam, převezme poziční parametr, který byl předán do shellu.
Příklad Bash For Loop 1. Rozbalte celý zip soubor
Následující příklad najde seznam souborů, které odpovídají „*.zip*“ v kořenovém adresáři, a vytvoří nový adresář ve stejném umístění, kde existuje soubor zip, a rozbalí obsah souboru zip.
# cat zip_unzip.sh #! /bin/bash # Find files which has .zip for file in `find /root -name "*.zip*" -type f` do # Skip the extension .zip dirname=`echo ${file} | awk -F'.' '{print $1}'` # Create the directory mkdir $dirname # Copy the zip file cp ${file} ${dirname} cd $dirname # Unzip the zip file from newly created directory unzip ${dirname}/$(echo ${file##/*/}) done
- V tomto příkladu příkaz find vrací seznam souborů, ze kterých bude každý soubor zpracován ve smyčce.
- Pro každou položku vytvoří adresář s názvem souboru zip a zkopíruje soubor zip do nově vytvořeného adresáře a odtud rozbalí soubor zip.
- Příkaz echo, echo ${file##/*/} vám poskytuje pouze název souboru, nikoli cestu.
# ./zip_unzip.sh Archive: /root/test2/test2.zip extracting: t1/p extracting: t1/q extracting: t1/r extracting: t1/s extracting: t1/t extracting: t1/u extracting: t1/v Archive: /root/test1/test1.zip extracting: t/a extracting: t/b extracting: t/c extracting: t/d extracting: t/e
Podobně jako smyčka Bash poskytuje Awk také smyčku for a while, jak jsme probrali v našem článku Awk While a For Loop.
Bash For Loop – druhá metoda
Druhá forma smyčky for je podobná smyčce for v programovacím jazyce „C“, která má tři výrazy (inicializaci, podmínku a aktualizaci).
for (( expr1; expr2; expr3 )) do commands done
- Ve výše uvedeném bash pro syntaxi příkazu je před první iterací vyhodnocen výraz expr1. To se obvykle používá k inicializaci proměnných pro smyčku.
- Všechny příkazy mezi do a done se provádějí opakovaně, dokud není hodnota výrazu 2 TRUE.
- Po každé iteraci cyklu je vyhodnocen expr3. To se obvykle používá ke zvýšení čítače smyček.
Následující příklad generuje n počet náhodných čísel.
Bash pro příklad 2. Vygenerujte n náhodných čísel
$ cat random.sh #! /bin/bash echo -e "How many random numbers you want to generate" read max for (( start = 1; start <= $max; start++ )) do echo -e $RANDOM done $ ./random.sh How many random numbers you want to generate 5 6119 27200 1998 12097 9181
Ve výše uvedeném úryvku kódu cyklus for generuje náhodné číslo v maximálním počtu opakování. RANDOM je interní bash funkce, která vrací náhodné celé číslo při každém vyvolání.
Bash While Loop
Další iterační příkaz nabízený programovacím jazykem shell je příkaz while.
Syntax: while expression do commands done
Ve výše uvedené syntaxi cyklu while:
- zatímco, do, hotovo jsou klíčová slova
- Výraz je jakýkoli výraz, který vrací skalární hodnotu
- Příkaz While způsobí, že se provede blok kódu, zatímco zadaný podmíněný výraz je pravdivý.
Bash While Příklad 3. Zápis obsahu do souboru
Následující příklad čte data ze stdout a zapisuje je do souboru.
$ cat writefile.sh #! /bin/bash echo -e "Enter absolute path of the file name you want to create" read file while read line do echo $line >> $file done $ sh writefile.sh Enter absolute path of the file name you want to create /tmp/a while for until $ cat /tmp/a while for until
Výše uvedený příklad přečte název souboru od uživatele a načte řádky dat ze standardního parametru a každý řádek připojí k danému souboru. Když vstoupí EOF, čtení se nezdaří, takže smyčka končí.
Pokud píšete hodně bash skriptů, můžete použít editor Vim jako Bash IDE pomocí pluginu Vim bash-support, jak jsme probrali dříve.
Bash While Příklad 4. Přečtěte si obsah souboru
V předchozím příkladu čte data ze stdout a zapisuje je do souboru. V tomto příkladu přečte
obsah souboru a zapíše jej do stdout.
$ cat read.sh #! /bin/bash echo -e "Enter absolute path of the file name you want to read" read file exec <$file # redirects stdin to a file while read line do echo $line done $ ./read.sh Enter absolute path of the file name you want to read /tmp/a while for until
V tomto příkladu získá název souboru ke čtení a pomocí exec přesměruje stdin do souboru. Od tohoto okamžiku všechny stdin pocházejí z tohoto souboru, nikoli z klávesnice. příkaz read čte řádek ze stdin, takže zatímco smyčka čte stdin, dokud nenastane EOF.
Bash Until Loop
Příkaz till je syntaxí a funkcí velmi podobný příkazu while. Jediný skutečný rozdíl mezi těmito dvěma je v tom, že příkaz till vykoná svůj blok kódu, zatímco jeho podmíněný výraz je nepravdivý, a příkaz while spustí svůj blok kódu, zatímco jeho podmíněný výraz je pravdivý.
syntax: until expression do commands #body of the loop done
Ve výše uvedené syntaxi bash till:
kde dokud, do, hotovo jsou klíčová slova
vyjadřují jakýkoli podmíněný výraz
Bash až do příkladu 5. Monitorujte soubor protokolu
Tento příklad monitoruje velikost souboru protokolu, jakmile velikost souboru protokolu dosáhne 2000 bajtů, vezme si kopii tohoto souboru protokolu.
$ cat monitor.sh file=/tmp/logfile until [ $(ls -l $file | awk '{print $5}') -gt 2000 ] do echo "Sleeping for next 5 seconds" sleep 5 done date=`date +%s` cp $file "$file-"$date.bak $ ./monitor.sh Sleeping for next 5 seconds Sleeping for next 5 seconds $ ls -l /tmp/logfile* -rw-r--r-- 1 sss sss 2010 Jun 24 12:29 logfile -rw-r--r-- 1 sss sss 2005 Jun 24 16:09 logfile-1277474574.bak
Příkaz till pokračuje ve vykonávání těla cyklu, dokud se podmínka nestane pravdivou. V tomto příkladu je podmínkou velikost souboru větší než 2000 bajtů, takže soubor zkopíruje, jakmile dosáhne 2000 bajtů.
Nezapomeňte se také podívat na naše dřívější příklady Bash Array.
Bash až do příkladu 6. Čekání na spuštění stroje
Tento příklad se používá k čekání, až se stroj objeví, než provede ssh na tento stroj. Příkaz dokud smyčka skončí pouze tehdy, když ping poskytne odpovědi.
$ cat mac_wait.sh #! /bin/bash read -p "Enter IP Address:" ipadd echo $ipadd until ping -c 1 $ipadd do sleep 60; done ssh $ipadd $./mac_wait.sh Enter IP Address:192.143.2.10 PING 192.143.2.10 (192.143.2.10) 56(84) bytes of data. --- 192.143.2.10 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms PING 192.143.2.10 (192.143.2.10) 56(84) bytes of data. 64 bytes from 192.143.2.10: icmp_seq=1 ttl=64 time=0.059 ms --- 192.143.2.10 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.059/0.059/0.059/0.000 ms The authenticity of host '192.143.2.10 (192.143.2.10)' can't be established. Are you sure you want to continue connecting (yes/no)? yes
Dokud smyčka je docela užitečná na příkazovém řádku, jako způsob čekání na určité události.