Nekonečná smyčka while ve skriptu BASH. BASH: popis smyček for, while, till a příklady použití Příklad: hledání spustitelných souborů


Autor: Paul Cobbaut
Datum zveřejnění: 16. října 2014
Překlad: A. Panin
Datum překladu: 21. prosince 2014

Kapitola 22. Smyčky ve skriptech

testovací příkaz

Příkaz test umožňuje určit, zda je výraz pravdivý nebo nepravdivý. Začněme testováním, zda je celočíselná hodnota 10 větší než celočíselná hodnota 55. $ test 10 -gt 55 ; echo $? 1 $

Příkaz test vrátí 1, pokud je výraz nepravdivý. A jak uvidíte v následujícím příkladu, příkaz test vrátí 0, pokud se výraz vyhodnotí jako true. $ test 56 -gt 55 ; echo $? 0 $

Pokud vám vyhovuje více pracovat s řetězci true a false, můžete použít příkaz test, jak je uvedeno níže. $ test 56 -gt 55 && echo true || echo false true $ test 6 -gt 55 && echo true || echo falešný falešný

Příkaz test lze také nahradit hranatými závorkami, takže příkazy v příkladu níže jsou přesně stejné jako příkazy v příkladu výše. $ [ 56 -gt 55 ] && echo true || echo false true $ [ 6 -gt 55 ] && echo true || echo falešný falešný

Níže jsou uvedeny příklady implementací některých kontrol. Přehled najdete na stránce testu pro muže další funkce provádění různých kontrol. [ -d foo ] Existuje adresář foo? [ -e bar ] Existuje soubor bar? [ "/etc" = $PWD ] Je /etc ekvivalentní hodnotě $PWD? [ $1 != "secret" ] Liší se hodnota prvního parametru skriptu od tajného řetězce? [ 55 -lt $bar ] Je celočíselná hodnota 55 menší než hodnota $bar? [ $foo -ge 1000 ] Je hodnota $foo větší nebo rovna celočíselné hodnotě 1000? ["abc"< $bar ] Будет ли строка abc расположена выше значения переменной $bar в списке после сортировки? [ -f foo ] Является ли foo обычным файлом? [ -r bar ] Является ли bar čitelný soubor? [ foo -nt bar ] Je foo novější než bar ? [ -o nounset ] Je povolena volba shellu nounset?

Kontrolní operátory lze kombinovat s operátory odpovídajícími logické operace"A" a "NEBO". paul@RHEL4b:~$ [ 66 -gt 55 -a 66 -lt 500 ] && echo true || echo false true paul@RHEL4b:~$ [ 66 -gt 55 -a 660 -lt 500 ] && echo true || echo false false paul@RHEL4b:~$ [ 66 -gt 55 -o 660 -lt 500 ] && echo true || echo false true

Podmíněný skok, když jinak

Konstrukce if then else je určena k výběru možnosti kódu. Pokud je určitá podmínka pravdivá, bude proveden nějaký kód, jinak bude proveden jiný kód. Níže uvedený příklad kontroluje existenci souboru, načež se v případě potvrzení předpokladu o existenci souboru zobrazí odpovídající zpráva. #!/bin/bash if [ -f isit.txt ] pak echo soubor isit.txt existuje! jinak echo soubor isit.txt nebyl nalezen! fi

V případě, že ušetříme tento kód skript v souboru s názvem "choice", lze jej spustit stejným způsobem. $ ./choice soubor isit.txt nebyl nalezen! $ touch isit.txt $ ./choice soubor isit.txt existuje! $

Podmíněný skok if pak elif

Můžete zveřejnit nového operátora podmíněný skok, pokud je uvnitř bloku else pomocí operátoru elif. Níže je uveden jednoduchý příklad takového záznamu. #!/bin/bash count=42 if [ $count -eq 42 ] pak echo "42 je platná hodnota." elif [ $count -gt 42 ] a poté echo "Příliš mnoho." jinak echo "Nestačí." fi

pro smyčku

Níže uvedený příklad ukazuje syntaxi klasické smyčky for v bash shellu. pro i v 1 2 4 do echo $i hotovo

Příklad použití cyklu for kombinovaného s inline voláním shellu. #!/bin/ksh pro počítadlo v `seq 1 20` do echo počítání od 1 do 20, aktuální hodnota $counter sleep 1 done

Skript zcela podobný výše uvedenému lze vytvořit bez použití vestavěného příkazového shellu pomocí deklarace bash shellu pro rozsah hodnot (od value..to value). #!/bin/bash pro counter in (1..20) do echo counting od 1 do 20, aktuální hodnota $counter sleep 1 done

Tato smyčka for používá mechanismus pro vyhledávání souborů podle vzoru (implementovaný jako součást mechanismu rozšíření příkazů). Pokud jsou výše uvedené pokyny zveřejněny přímo v příkazový řádek, bude fungovat podobně. kahlan@soleexp11$ ls count.ksh go.ksh kahlan@soleexp11$ pro soubor v *.ksh ; do cp $soubor $soubor.zaloha ; hotovo kahlan@soleexp11$ ls count.ksh count.ksh.backup go.ksh go.ksh.backup

zatímco smyčka

Níže je uveden jednoduchý příklad použití smyčky while. i=100; zatímco [ $i -ge 0 ] ; do echo Odpočítávání od 100 do 0, aktuální hodnota $i; nechej--; Hotovo

Nekonečné smyčky lze implementovat pomocí deklarací while true nebo while:, kde symbol: je ekvivalentem chybějící operace v Korn shellu a bash. #!/bin/ksh # nekonečná smyčka while: do echo hello sleep 1 done

Až do smyčky

Níže je uveden jednoduchý příklad použití smyčky dokud. nechť i=100; dokud [ $i -le 0 ] ; do echo Odpočítávání od 100 do 1, aktuální hodnota $i; nechej--; Hotovo

Cvičení: Testy a smyčky ve skriptech

3. Vytvořte skript, který bude používat smyčku while k počítání od 3 do 7.

4. Vytvořte skript, který bude používat cyklus dokud k odpočítávání od 8 do 4.

5. Vytvořte skript, který bude počítat soubory s příponou .txt v aktuálním adresáři.

6. Použijte příkaz if ve vytvořeném skriptu, aby fungoval správně, pokud v aktuálním adresáři nejsou žádné soubory s příponou .txt.

Správný postup plnění praktického úkolu: kontroly a smyčky ve skriptech

1. Vytvořte skript, který bude používat cyklus for k počítání od 3 do 7.

#!/bin/bash for i in 3 4 5 6 7 do echo Počítání od 3 do 7, aktuální hodnota $i hotovo

2. Vytvořte skript, který bude používat cyklus for k počítání od 1 do 17000.

Shell bash podporuje smyčky, které vám umožňují iterovat sekvence hodnot. Tak to je základní struktura takové cykly:

Pro var v seznamu proveďte příkaz hotovo
V každé iteraci cyklu bude proměnná var zapsána na další hodnotu od seznam. První průchod smyčkou tedy použije první hodnotu ze seznamu. Ve druhé - druhé a tak dále - dokud smyčka nedosáhne posledního prvku.

Iterace přes jednoduché hodnoty

Snad nejjednodušším příkladem smyčky for v bash skriptech je iterace přes seznam jednoduchých hodnot:

#!/bin/bash pro var v první druhé třetině čtvrté páté do echo Položka $var hotovo
Výsledky tohoto skriptu jsou uvedeny níže. Jasně vidíte, že proměnná $var obsahuje prvky ze seznamu postupně. To se děje, dokud cyklus nedosáhne posledního z nich.


Jednoduché pro smyčku

Upozorňujeme, že proměnná $var si při výstupu ze smyčky zachovává svou hodnotu, její obsah lze měnit a obecně s ní lze pracovat jako s jakoukoli jinou proměnnou.

Iterace přes komplexní hodnoty

Seznam použitý k inicializaci cyklu for může obsahovat nejen jednoduché řetězce skládající se z jednoho slova, ale také celé fráze, které obsahují několik slov a interpunkčních znamének. Může to vypadat například takto:

#!/bin/bash pro var v první "druhé" "třetí" "Udělám to" do echo "Toto je: $var" hotovo
To se stane poté, co tato smyčka projde seznamem. Jak vidíte, výsledek je vcelku očekávaný.


Iterace přes komplexní hodnoty
TNW-CUS-FMP – promo kód na 10% slevu na naše služby, k dispozici pro aktivaci do 7 dnů“

Inicializace smyčky se seznamem získaným z výsledků příkazu

Dalším způsobem, jak inicializovat cyklus for, je předat mu seznam, který je výsledkem příkazu. Zde se k jejich provedení a získání výsledků jejich práce používá substituce příkazů.

#!/bin/bash file="myfile" pro var v $(cat $file) do echo " $var" hotovo
Tento příklad používá příkaz cat, který čte obsah souboru. Výsledný seznam hodnot je předán do smyčky a zobrazen na obrazovce. Vezměte prosím na vědomí, že soubor, ke kterému přistupujeme, obsahuje seznam slov oddělených novými řádky, nepoužívají se žádné mezery.


Smyčka, která prochází obsahem souboru

Zde musíme vzít v úvahu, že takový přístup, pokud se očekává řádkové zpracování dat, nebude fungovat pro soubor složitější struktury, jehož řádky mohou obsahovat více slov oddělených mezerami. Smyčka zpracuje jednotlivá slova, nikoli řádky.

Co když to není to, co vůbec potřebujete?

Polní separátory

Důvodem výše uvedené funkce je speciál proměnná prostředí, který se nazývá IFS (Internal Field Separator) a umožňuje určit oddělovače polí. Ve výchozím nastavení bash shell považuje následující znaky za oddělovače polí:
  • Prostor
  • Znak tabulátoru
  • Znak posuvu řádku
Pokud bash narazí na některý z těchto znaků v datech, předpokládá, že mu předchází další nezávislá hodnota v seznamu.

Chcete-li problém vyřešit, můžete dočasně změnit proměnnou prostředí IFS. Zde je návod, jak to udělat ve skriptu bash, za předpokladu, že jako oddělovač polí potřebujete pouze nový řádek:

IFS=$"\n"
Jakmile tento příkaz přidáte do svého bash skriptu, bude fungovat podle očekávání, bude ignorovat mezery a tabulátory a jako oddělovače polí bude nakládat pouze se znaky nového řádku.

#!/bin/bash file="/etc/passwd" IFS=$"\n" pro var v $(cat $file) do echo " $var" hotovo
Pokud je tento skript spuštěn, vypíše přesně to, co je od něj požadováno, a v každé iteraci cyklu poskytne přístup k dalšímu řádku zapsanému do souboru.


Procházení souboru po řádcích ve smyčce for

Oddělovače mohou být i jiné znaky. Například výše jsme zobrazili obsah souboru /etc/passwd. Uživatelská data na řádcích jsou oddělena dvojtečkami. Pokud potřebujete zpracovat takové řetězce ve smyčce, IFS lze nakonfigurovat takto:

Procházení souborů obsažených v adresáři

Jedním z nejběžnějších použití smyček for v bash skriptech je procházení souborů umístěnými v adresáři a zpracování těchto souborů.

Zde je například postup, jak zobrazit seznam souborů a složek:

#!/bin/bash pro soubor v /home/likegeeks/* proveďte if [ -d "$soubor" ] potom echo "$soubor je adresář" elif [ -f "$soubor" ] a poté echo "$soubor je soubor" je hotovo
Pokud jste pochopili předchozí materiál v této sérii článků, měli byste rozumět struktuře konstrukce if-then a také tomu, jak rozlišit soubor od složky. Pokud je pro vás obtížné výše uvedenému kódu porozumět, přečtěte si tento materiál znovu.

To je to, co skript vypíše.


Zobrazení obsahu složky

Věnujte pozornost tomu, jak inicializujeme smyčku, jmenovitě divoká karta"*" na konci adresy složky. Tento symbol lze považovat za zástupný znak, který znamená: „všechny soubory s libovolnými názvy“. umožňuje organizovat automatická substituce názvy souborů, které odpovídají vzoru.

Při testování podmínky v příkazu if uzavřeme název proměnné do uvozovek. To se děje proto, že název souboru nebo složky může obsahovat mezery.

C-styl pro smyčky

Pokud jste obeznámeni s programovacím jazykem C, syntaxe pro popis smyček bash for vám může připadat divná, protože jste zjevně zvyklí popisovat smyčky tímto způsobem:

Pro (i = 0; i< 10; i++) { printf("number is %d\n", i); }
V bash skriptech můžete použít pro smyčky, jejichž popis vypadá velmi podobně jako smyčky ve stylu C, i když existují určité rozdíly. Cyklický diagram s tímto přístupem vypadá takto:

For ((počáteční hodnota proměnné; podmínka pro ukončení smyčky; změna proměnné))
V bash to může být zapsáno takto:

Pro ((a = 1; a< 10; a++))
Zde je pracovní příklad:

#!/bin/bash pro ((i=1; i<= 10; i++)) do echo "number is $i" done
Tento kód vypíše seznam čísel od 1 do 10.

Smyčka ve stylu C

zatímco smyčka

Konstrukce for není jediným způsobem, jak organizovat smyčky v bash skriptech. Můžete zde také použít smyčky while. V takové smyčce můžete zadat příkaz pro kontrolu určité podmínky a provést tělo smyčky, dokud testovaná podmínka nevrátí nulu nebo signál pro úspěšné dokončení určité operace. Když podmínka smyčky vrátí nenulovou hodnotu, což znamená chybu, smyčka se zastaví.

Zde je schéma organizace smyček while
zatímco příkaz pro kontrolu stavu
dělat
ostatní týmy
Hotovo

Podívejme se na příklad skriptu se smyčkou, jako je tato:

#!/bin/bash var1=5 while [ $var1 -gt 0 ] do echo $var1 var1=$[ $var1 - 1 ] hotovo
Na vstupu do smyčky se kontroluje, zda je proměnná $var1 větší než nula. Pokud ano, provede se tělo cyklu, ve kterém se jedna odečte od hodnoty proměnné. To se děje v každé iteraci a hodnotu proměnné vytiskneme do konzole, než dojde k její úpravě. Jakmile $var1 dosáhne hodnoty 0, smyčka se zastaví.

Výsledek smyčky while

Pokud neupravíte proměnnou $var1, skript skončí v nekonečné smyčce.

Vnořené smyčky

Můžete použít libovolné příkazy v těle smyčky, včetně spouštění dalších smyček. Takové konstrukce se nazývají vnořené smyčky:

#!/bin/bash pro ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
Níže je uveden výstup tohoto skriptu. Jak vidíte, nejprve se provede první iterace vnější smyčky, poté tři iterace vnitřní smyčky, po jejím dokončení přichází na řadu opět vnější smyčka, poté opět vnitřní.

Vnořené smyčky

Zpracování obsahu souboru

Nejčastěji se ke zpracování souborů používají vnořené smyčky. Vnější smyčka tedy iteruje přes řádky souboru a vnitřní smyčka již pracuje s každým řádkem. Zde je například, jak vypadá zpracování souboru /etc/passwd:

#!/bin/bash IFS=$"\n" pro položku v $(cat /etc/passwd) do echo "Hodnoty v $entry –" IFS=: pro hodnotu v $entry do echo " $value" hotovo Hotovo
V tomto skriptu jsou dvě smyčky. První prochází řádky pomocí znaku nového řádku jako oddělovače. Vnitřní je zaneprázdněno analýzou řetězců, jejichž pole jsou oddělena dvojtečkami.

Zpracování dat souboru

Tento přístup lze použít při zpracování souborů CSV nebo jakýchkoli podobných souborů zapsáním oddělovacího znaku do proměnné prostředí IFS podle potřeby.

Řízení cyklu

Možná, že po vstupu do smyčky ji budete muset zastavit, když proměnná smyčky dosáhne určité hodnoty, která neodpovídá původně zadané podmínce pro ukončení smyčky. Bude v takové situaci nutné čekat na normální dokončení cyklu? Samozřejmě ne a v takových případech se budou hodit následující dva příkazy:
  • přestávka
  • pokračovat

příkaz přerušení

Tento příkaz umožňuje přerušit provádění smyčky. Lze jej použít pro smyčky for a while:

#!/bin/bash pro var1 v 1 2 3 4 5 6 7 8 9 10 proveďte if [ $var1 -eq 5 ] a poté přerušte fi echo "Číslo: $var1" hotovo
Taková smyčka za normálních podmínek projde celým seznamem hodnot ze seznamu. V našem případě však bude jeho provádění přerušeno, když je proměnná $var1 rovna 5.

Předčasné ukončení cyklu for

Zde je to samé, ale pro smyčku while:

#!/bin/bash var1=1 while [ $var1 -lt 10 ] proveďte if [ $var1 -eq 5 ] then break fi echo "Iterace: $var1" var1=$(($var1 + 1)) hotovo
Příkaz break, který se provede, když $var1 dosáhne 5, přeruší smyčku. Konzole zobrazí to samé jako v předchozím příkladu.

pokračovat příkazem

Když je tento příkaz nalezen v těle smyčky, aktuální iterace skončí dříve a začne další, aniž by se smyčka opustila. Podívejme se na příkaz continue ve smyčce for:

#!/bin/bash pro ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
Když je splněna podmínka uvnitř smyčky, tedy když $var1 je větší než 5 a menší než 10, shell provede příkaz continue. To má za následek přeskočení zbývajících příkazů v těle smyčky a přechod k další iteraci.

Příkaz continue ve smyčce for

Výstup zpracování běží ve smyčce

Výstup dat ze smyčky lze zpracovat buď přesměrováním výstupu, nebo jeho předáním do potrubí. To se provádí přidáním příkazů pro zpracování výstupu za příkaz done.

Například místo zobrazení výstupu ve smyčce na obrazovce můžete vše zapsat do souboru nebo předat jinam:

#!/bin/bash pro ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt echo "dokončeno."
Shell vytvoří soubor myfile.txt a přesměruje výstup příkazu for do tohoto souboru. Otevřete soubor a ujistěte se, že obsahuje přesně to, co očekáváme.

Přesměrovat výstup smyčky do souboru

Příklad: Vyhledejte spustitelné soubory

Využijme toho, co jsme již probrali, a napišme něco užitečného. Pokud například potřebujete zjistit, které spustitelné soubory jsou v systému k dispozici, můžete prohledat všechny složky zaznamenané v proměnné prostředí PATH. Již máme celý arzenál nástrojů, které k tomu potřebujeme, jen to musíme dát dohromady:

#!/bin/bash IFS=: pro složku v $PATH udělat echo "$folder:" pro soubor ve $složce/* udělat if [ -x $file ] potom echo " $soubor" fi hotovo
Tento malý a jednoduchý skript nám umožnil získat seznam spustitelných souborů uložených ve složkách z PATH.

Vyhledávání spustitelných souborů ve složkách z proměnné PATH

Výsledek

Dnes jsme mluvili o smyčkách for a while v bash skriptech, jak je spouštět a jak je spravovat. Nyní víte, jak zpracovávat řetězce s různými oddělovači ve smyčkách, víte, jak přesměrovat výstup dat ve smyčkách do souborů, jak prohlížet a analyzovat obsah adresářů.

Pokud předpokládáme, že jste vývojář bash skriptů, který o nich ví jen to, co je uvedeno v první části této série článků a v této druhé, pak už můžete napsat něco užitečného. Před námi je třetí díl, po jehož pochopení se naučíte, jak předávat parametry a přepínače příkazového řádku do bash skriptů a co s tím vším dělat.

Stručný popis rozdílu v typech smyček:

for - bude provádět akci, dokud existují objekty k provedení (například čtení proudu ze standardního vstupu, souboru nebo funkce);
while - provede akci do stav je pravda;
dokud - bude prováděno tak dlouho, dokud stav se nestane pravdou, tzn. zatím je to falešné.

PRO Smyčka

Podívejme se na tuto verzi skriptu se smyčkou:

$ cat loop.sh #!/bin/bash pro proměnnou v `ls -1` do echo "$variable" hotovo

Syntaxe je velmi jednoduchá a je zcela jasně ukázána v příkladu:

for (spustit smyčku) proměnnou (deklarovat proměnnou, se kterou budeme provádět akce) v (odeslat tok do smyčky) `ls -1` (příkaz, který se má provést a předat proměnné $variable). Do a done jsou „tělo“ smyčky, ve kterém budou provedeny hlavní akce s přijatými daty, a echo „$proměnná“ je skutečná akce provedená smyčkou.

Nyní trochu změníme příklad a místo explicitního zadání příkazu použijeme druhou proměnnou:

$ cat loop.sh #!/bin/bash ls=`ls -1` pro proměnnou v $ls do echo "$variable" hotovo

Nyní je příkaz ls -1 předán v samostatné proměnné, což umožňuje pracovat se smyčkou pružněji. Místo proměnné ve smyčce můžete také použít funkci:

$ cat loop.sh #!/bin/bash lsl () ( ls -1 ) pro proměnnou v `lsl` do echo "$variable" hotovo

Hlavní podmínkou cyklu for je, že bude proveden, pokud příkaz, který mu byl předán, obsahuje objekty pro akci. Na základě výše uvedeného příkladu - pokud má ls -1 soubory k zobrazení - smyčka je předá proměnné a spustí "tělo smyčky". Jakmile seznam souborů v adresáři skončí, smyčka dokončí své provádění.

Udělejme příklad trochu složitější.

Adresář obsahuje seznam souborů:

$ ls -1 soubor1 soubor2 soubor3 soubor4 soubor5 loop.sh nofile1 nofile2 nofile3 nofile4 nofile5

Musíme z nich vybrat pouze ty, které nemají slovo " Ne«:

$ cat loop.sh #!/bin/bash lsl=`ls -1` pro proměnnou v $lsl do echo "$variable" | grep -v "no" hotovo $ ./loop.sh soubor1 soubor2 soubor3 soubor4 soubor5 loop.sh

Můžete také použít podmíněné výrazy ve smyčce ( podmíněné výrazy) […] ke kontrole podmínek a příkazu break k přerušení smyčky, pokud je podmínka spuštěna.

Zvažte tento příklad:

$ cat loop.sh #!/bin/bash lsl=`ls -1` pro proměnnou v $lsl proveďte if [ $proměnná != "loop.sh" ] potom echo "$proměnná" | grep -v "ne" else break fi hotovo

Cyklus bude pokračovat, dokud nenarazíte na soubor loop.sh. Jakmile provádění smyčky dosáhne tohoto souboru, smyčka bude přerušena příkazem break:

$ ./loop.sh soubor1 soubor2 soubor3 soubor4 soubor5

Dalším příkladem je použití aritmetických operací bezprostředně před provedením těla smyčky:

$ cat loop.sh #!/bin/bash for ((počet=1; počet<11; count++)) do echo "$count" done

Zde nastavíme tři řídicí příkazy - počet=1, řídicí podmínku - zatímco počet je menší než 11, a příkaz k provedení - počet +1:

smyčky WHILE a UNTIL

Jednoduchý příklad, který jasně ukazuje, jak cyklus while funguje:

$ cat loop.sh #!/bin/bash count=0 while [ $count -lt 10 ] do ((count++)) echo $count done

Nastavíme proměnnou $count na nulu a poté spustíme smyčku whi le s podmínkou „když je $count menší než deset, proveďte smyčku“. V těle smyčky provedeme postfixový přírůstek+1 k proměnné $count a výsledek se vytiskne na stdout.

Výsledek provedení:

$ ./loop.sh 1 2 3 4 5 6 7 8 9 10

Jakmile hodnota proměnné $count dosáhla 10, smyčka se zastavila.

Dobrý příklad "nekonečné" smyčky, která ukazuje, jak funguje while:

$ cat loop.sh #!/bin/bash count=10 while [ 1 = 1 ] do ((count++)) echo $count done $ ./loop.sh ... 5378 5379 5380 5381 5382 5383 ^C

Smyčka do funguje podobně, ale v opačném směru:

$ cat loop.sh #!/bin/bash count=0 dokud [ $count -gt 10 ] do ((count++)) echo $count done

Zde nastavíme podobnou podmínku, ale místo „zatímco je proměnná menší než 10“, zadáme „dokud se proměnná nestane větší než 10“. Výsledek provedení:

$ ./loop.sh 1 2 3 4 5 6 7 8 9 10 11

Pokud je výše uvedený příklad „nekonečné smyčky“ proveden pomocí dokud, nevypíše nic, na rozdíl od while:

$ cat loop.sh #!/bin/bash count=10 dokud [ 1 = 1 ] do ((count++)) echo $count done $ ./loop.sh $

Protože " stav"původně" skutečný"—tělo smyčky nebude provedeno.

Stejně jako ve smyčce for můžete používat funkce v while a till. Například smyčka z reálného skriptu, která kontroluje stav serveru Kocour(PID je převzato ze systému SLES, může se lišit v jiných systémech), mírně zjednodušená verze:

$ cat loop.sh #!/bin/bash check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) zatímco check_tomcat_status proveďte if [ -n "$ RUN" ] pak printf "VAROVÁNÍ: Tomcat stále běží s PID $RUN." jinak printf "Tomcat zastaven, pokračuje...nn" break fi hotovo

Výsledek provedení:

$ ./loop.sh VAROVÁNÍ: Tomcat stále běží s PID 14435 26548. VAROVÁNÍ: Tomcat stále běží s PID 14435 26548. VAROVÁNÍ: Tomcat stále běží s PID 14435 26548. VAROVÁNÍ: Tomcat stále běží s PID5 Tomcat 26544: běží s PID 14435 26548.VAROVÁNÍ: Tomcat stále běží s PID 14435 26548.VAROVÁNÍ: Tomcat stále běží s PID 14435 26548.VAROVÁNÍ: Tomcat stále běží s PID 14435

Plná verze:

Check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(tisk $2)"` ) while check_tomcat_status; proveďte if [ -n "$RUN" ] then printf "VAROVÁNÍ: Tomcat stále běží s PID $RUN. Zastavit jej?" odpovězte "Zastavuji Tomcat..." "Probíhá instalace..." && $CATALINA_HOME/bin/shutdown sh 2&>1 /dev/null || break sleep 2 if [ -n "$RUN" ] then printf "Tomcat stále běží. Zabít ho?" odpověď "Killing Tomcat..." "Probíhá instalace...n" && zabít $RUN || break sleep 2 fi else printf "Tomcat zastaven, pokračuje...nn" break fi hotovo

Funkce odpovědi byla popsána v článku, ale zde je použita mírně vylepšená verze:

Odpověď () (při čtení odpovědi; do echo case $response in |) printf "$1n" return 0 break ;; |) printf "$2n" return 1 break ;; *) printf "Zadejte prosím Y(ano) nebo N(ne)!" esac hotovo )

Zde bylo možné použít while i till - ale ne smyčku for, protože for by jednou fungovalo (obdrželo PID a skončilo).

Smyčky jsou extrémně pohodlná věc při psaní jakýchkoli programů nebo skriptů, spíše dokonce nezbytná. Umožňují nám spustit určitou část kódu zadaný počet opakování. Přirozeně, bash má několik typů smyček. Popíšeme si cykly for in, for, while, than. Přestože for in a for jsou považovány za různé syntaxe téhož výroku, podle mého názoru se od sebe liší více než while od do.

Smyčka s počítadlem pro dovnitř:

Cyklus pro v Jedná se o smyčku s počítadlem. Blok kódu umístěný v těle smyčky se opakuje tolikrát, kolikrát je hodnot obsažených v seznamu operátoru for in a při každém opakování se proměnná čítače (zde se nazývá var, ale samozřejmě můžete to nazvat jak chcete) má hodnotu dalšího prvku seznamu.
Pokud je klíčové slovo do na stejném řádku jako slovo pro, musíte za seznam argumentů (před do) vložit středník.
Každý z prvků<список>může obsahovat několik argumentů. To je užitečné při zpracování skupin parametrů. V tomto případě vynutit analýzu každého z argumentů v<списке>, musíte použít nastavenou instrukci
Proměnnou můžete použít jako seznam v cyklu for.
V<списке>Smyčka for může používat názvy souborů, které zase mohou obsahovat zástupné znaky. To může být velmi užitečné při práci s velkým množstvím souborů.
Li<список>není specifikován v cyklu for, pak se jako to použije proměnná $@ - seznam argumentů příkazového řádku.
Při vytváření seznamu argumentů můžete použít substituci příkazů ve smyčce for.
Výstup smyčky může být přesměrován ze stdout do souboru nebo někam jinam (více se o tom můžete dozvědět, když se podíváte na přesměrování I/O).

Syntax:
pro var in<список>
dělat
<выполняемые команды>
Hotovo

Příklad:
pro jména ve jméno1 jméno2 jméno3 jméno4
dělat
echo $names
Hotovo

Operátor smyčky pro má jiný způsob zápisu - velmi podobný syntaxi operátoru for v jazyce C. V tomto případě se při inicializaci čítačů nastaví počáteční hodnoty proměnných nebo jedné proměnné a po každém průchodu smyčkou podmínka je zaškrtnuto, pokud kontrola vrátí hodnotu true, začne další průchod smyčky. V bloku<приращение счётчиков>hodnota našich čítačů proměnných se musí nutně změnit (ne nutně nahoru), abychom při kontrole podmínky dříve nebo později dostali hodnotu false, jinak smyčka nikdy neskončí. Velmi pohodlná a hlavně známá možnost, pokud je třeba jakoukoli operaci opakovat stanovený početkrát.

S podobnou syntaxí:
pro ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
dělat
<выполняемые команды>
Hotovo

Příklad:
pro ((var=1; var<= LIMIT ; var++))
dělat
echo $var
Hotovo

while smyčka:

Jedná se o celkem jednoduchou konstrukci, která kontroluje stav za operátorem zatímco a pokud je tato podmínka pravdivá, provede blok příkazů umístěný mezi slovy do a done a poté znovu přejde ke kontrole podmínky. Pokud kontrola vrátí hodnotu false, cyklus skončí a začnou se provádět následující příkazy: Hotovo. Je nezbytně nutné to zajistit<проверка условия>záviselo na kódu běžícím ve smyčce; jinak, pokud se výsledek kontroly nezmění, dostanete nekonečnou smyčku.
Standardní vstupní zařízení pro smyčku while lze přesměrovat do souboru pomocí příkazu redirection< в конце цикла.

Syntax:
zatímco<Проверка условия>
dělat
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
Hotovo

Příklad:
zatímco [ $var0 -eq 100]
dělat
echo $var
var++
Hotovo

Operátor zatímco může mít několik podmínek. Ale pouze poslední z nich určuje možnost pokračování cyklu. V tomto případě bude syntaxe operátoru smyčky odlišná od obvyklé.
Syntax(Ještě jednou opakuji, že pouze poslední podmínka ovlivňuje provedení smyčky) :
zatímco
<условие1>
<условие2>

<условиеN>
dělat
<выполняемые команды - тело цикла>
Hotovo

Do smyčky:

Operátor až do je velmi podobný while, také vyhodnotí podmínku, ale provede tělo cyklu, pokud je výsledek výpočtu nepravdivý. Může se to zdát neobvyklé, ale dokud nevyhodnotí podmínku před prvním průchodem smyčky, jako while, a ne po něm. Stejně jako u cyklů for/in musíte při umístění klíčového slova do na stejný řádek jako deklarace cyklu vložit znak ";". před tím.
Stejně jako v předchozím případě je důležité si uvědomit, že podmínka musí záviset na operacích v těle smyčky, jinak se náš skript nikdy nedokončí.

Syntax:
až do<Проверка условия>
dělat
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
Hotovo

Příklad:
dokud [ $var0 -gt 100] # Podmínka je zkontrolována na začátku iterace.
dělat
echo $var
var--
Hotovo

To asi zatím stačí. :)

  • Zadní
  • Vpřed

Nové články:

  • Zjišťování sítě se nezapne ve Windows 7/8/2008/2012
  • Chyba: Tuto aplikaci se nepodařilo spustit, protože nemohla najít nebo načíst plugin platformy Qt „windows“.
  • Konfigurace automatického restartu pracovních procesů rphost.exe na serveru 1C 8.3
  • Jak zmenšit velikost transakčního protokolu (.ldf) v MS SQL 2008/20012

    MS SQL, jako každý slušný průmyslový DBMS, spolu s databází uchovává protokoly transakcí, které vám umožňují vrátit stav...

0 Meeran Bala-Kumaran

Opravdu se snažím pochopit, proč tato smyčka while nikdy nekončí, když smyčka začíná, moje proměnná LOC je nastavena na Testing/ což je adresář, který jsem vytvořil pro testování tohoto programu, má následující rozložení:

Chci, aby smyčka skončila, jakmile všechny adresáře použijí funkci "count".
Zde je to, co jsem zkusil;

Zkontroloval jsem funkci počítání a nevytváří nekonečnou smyčku

Zkusil jsem spustit algoritmus ručně

PARSE=1 LOC=$LOC/ počet AVAILABLEDIR=$(ls $LOC -AFl | sed "1 d" | grep "/$" | awk "( tisk $9 )") zatímco [ $PARSE = "1" ] proveďte if [[ $(AVAILABLEDIR[@]) == "" ]]; potom PARSE=0 fi DIRBASE=$LOC pro a v $(AVAILABLEDIR[@]); do LOC="$(DIRBASE)$(a)" LOCLIST="$LOCLIST $LOC" počet proveden pro a v $(LOCLIST[@]); do TMPAVAILABLEDIR=$(ls $a -AFl | sed "1 d" | grep "/$" | awk "( tisk $9 )") PREPEND=$a if [[ $(TMPAVAILABLEDIR[@]) == "" ] ]; pak pokračujte fi pro a v $(TMPAVAILABLEDIR[@]); do TMPAVAILABLEDIR2="$TMPAVAILABLEDIR2 $(PREPEND[@])$(a)" hotovo NEWAVAILABLEDIR="$NEWAVAILABLEDIR $TMPAVAILABLEDIR2" hotovo AVAILABLEDIR=$NEWAVAILABLEDIR NEWAVAILABLEDIR="" LOC="" hotovo

Opravdu bojuji a každý příspěvek by byl velmi oceněn, snažil jsem se na to přijít poslední dvě hodiny.

bash nekonečná smyčka

4 odpovědi

Měli byste zkusit spustit skript s argumentem -x nebo jej napsat na první řádek:

#!/bin/bash -x

Pak vám řekne všechno, co dělá.

V tomto případě si můžete všimnout dvou chyb:

    Nikdy znovu nenačtete TMPAVAILABLEDIR2

    Provádíte také ls na běžných souborech.

Pokud se opravdu musíte vyhnout rekurzi, zkuste toto, zcela bez rekurze:

#!/bin/bash count() ( echo counting "$1" ) todo=(Testing) while test $(#todo[@]) != 0 do doit=("$(todo[@])") todo= () pro dir v "$(doit[@])" proveďte pro položku v "$dir"/* # pokud je dir prázdný, zobrazí se položka s názvem "*" do test -e "$entry" || pokračovat # přeskočit záznam "*" prázdného dir count "$entry" test -d "$entry" || pokračovat todo+=("$entry") hotovo hotovo hotovo

Řekněte mi však, proč nemůžete použít rekurzi? Je to nějaký druh alergie? Slib? Existují nějaké místní zákony proti rekurzivnímu softwaru tam, kde žijete?

Napsal jste, že chcete provést "spočet" všech střihů. Podívejte se na možnosti vyhledávání:

Najděte $LOC -typ d | při čtení dir; do cd $LOC cd $(dir) count hotovo

nebo kratší (když váš čítač funkcí má adresář jako parametr 1)

Najděte $LOC -typ d | počet xargů

Teď vidím, že nechcete použít find nebo ls -R (rekurzivní funkce). Pak byste si měli vytvořit vlastní rekurzivní funkci jako

Funkce parseDir ( ls -d */ $1 | při čtení adresáře; počítejte parseDir $1/$dir hotovo )

Nevím, jestli to bude fungovat, ale je to zajímavá otázka, na kterou jsem nemohl přestat myslet. Hodně štěstí

Zatímco pravda; udělat pro slovo v "$(echo *)" ; udělat if [[ -d "$slovo" ]] ; potom d[$((i++))]="$PWD"/"$word" elif [[ -f "$word" ]] ;pak f[$((j++))]="$PWD"/"$ word" fi hotovo [[ $k -gt $i ]] && cd .. cd "$d[$((k++))]" || přestávka hotová