Beskonačna while petlja u BASH skripti. BASH: opis for, while, until petlji i primjeri korištenja Primjer: traženje izvršnih datoteka


Autor: Paul Cobbaut
Datum objave: 16. listopada 2014
Prijevod: A. Panin
Datum prijevoda: 21. prosinca 2014

Poglavlje 22. Petlje u skriptama

testna naredba

Naredba test vam omogućuje da odredite je li izraz istinit ili lažan. Počnimo s testiranjem je li vrijednost cijelog broja 10 veća od vrijednosti cijelog broja 55. $ test 10 -gt 55 ; echo $? 1 $

Testna naredba vraća 1 ako je izraz lažan. I, kao što ćete vidjeti u sljedećem primjeru, naredba test će vratiti 0 ako se izraz ocijeni kao istinit. $ test 56 -gt 55 ; echo $? $0

Ako vam je ugodnije raditi s nizovima true i false, možete koristiti test naredbu kao što je prikazano u nastavku. $ test 56 -gt 55 && echo true || echo false true $ test 6 -gt 55 && echo true || echo lažno lažno

Testna naredba također se može zamijeniti uglatim zagradama, tako da su naredbe u donjem primjeru potpuno iste kao naredbe u gornjem primjeru. $ [ 56 -gt 55 ] && echo true || echo false true $ [ 6 -gt 55 ] && echo true || echo lažno lažno

Ispod su primjeri implementacija nekih provjera. Pogledajte stranicu za testiranje čovjeka za pregled dodatne mogućnosti provođenje raznih provjera. [ -d foo ] Postoji li imenik foo? [ -e bar ] Postoji li bar datoteka? [ "/etc" = $PWD ] Je li /etc ekvivalentan vrijednosti $PWD? [ $1 != "secret" ] Razlikuje li se vrijednost prvog parametra skripte od tajnog niza? [ 55 -lt $bar ] Je li vrijednost cijelog broja 55 manja od vrijednosti $bar ? [ $foo -ge 1000 ] Je li vrijednost $foo veća ili jednaka cjelobrojnoj vrijednosti 1000? ["abc"< $bar ] Будет ли строка abc расположена выше значения переменной $bar в списке после сортировки? [ -f foo ] Является ли foo обычным файлом? [ -r bar ] Является ли bar čitljiva datoteka? [foo -nt bar] Je li foo noviji od bara? [ -o skup imenica ] Je li omogućena opcija ljuske za skup imenica?

Operatori provjere mogu se kombinirati s odgovarajućim operatorima logičke operacije"I" i "ILI". 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 lažno istinito

Uvjetni skok if then else

Konstrukcija if then else namijenjena je odabiru opcije koda. Ako je određeni uvjet istinit, neki kod će se izvršiti, u protivnom će se izvršiti neki drugi kod. Primjer u nastavku provjerava postojanje datoteke, nakon čega se, ako se pretpostavka o postojanju datoteke potvrdi, prikazuje odgovarajuća poruka. #!/bin/bash if [ -f isit.txt ] then echo datoteka isit.txt postoji! inače echo datoteka isit.txt nije pronađena! fi

U slučaju da štedimo ovaj kod skriptu u datoteci pod nazivom "izbor", može se izvršiti na isti način. $ ./datoteka izbora isit.txt nije pronađena! $ dodirnite isit.txt $ ./datoteka izbora isit.txt postoji! $

Uvjetni skok if then elif

Možete objaviti novi operater uvjetni skok ako je unutar else bloka pomoću operatora elif. Ispod je jednostavan primjer takvog unosa. #!/bin/bash count=42 if [ $count -eq 42 ] then echo "42 je važeća vrijednost." elif [ $count -gt 42 ] zatim ponovite "Previše." else echo "Nije dovoljno." fi

za petlju

Primjer u nastavku prikazuje sintaksu klasične for petlje u bash ljusci. for i in 1 2 4 do echo $i done

Primjer korištenja for petlje u kombinaciji s inline pozivom ljuske. #!/bin/ksh za brojač u `seq 1 20` do echo brojanja od 1 do 20, trenutna vrijednost $counter sleep 1 done

Skripta potpuno slična onoj prikazanoj gore može se stvoriti bez upotrebe ugrađene naredbene ljuske korištenjem bash deklaracije ljuske za raspon vrijednosti (od vrijednosti..do vrijednosti). #!/bin/bash za brojač u (1..20) izvrši brojanje odjeka od 1 do 20, trenutna vrijednost $brojač spavanje 1 gotovo

Ova for petlja koristi mehanizam za pretraživanje datoteka prema uzorku (implementiran kao dio mehanizma proširenja naredbi). Ako su gore navedene upute objavljene izravno u naredbeni redak, funkcionirat će na sličan način. kahlan@solexp11$ ls count.ksh go.ksh kahlan@solexp11$ za datoteku u *.ksh ; do cp $file $file.backup ; gotovo kahlan@solexp11$ ls count.ksh count.ksh.backup go.ksh go.ksh.backup

while petlja

Dolje je jednostavan primjer korištenja while petlje. i=100; dok [ $i -ge 0 ] ; do echo Odbrojavanje od 100 do 0, trenutna vrijednost $i; neka ja--; učinjeno

Beskonačne petlje mogu se implementirati pomoću deklaracija while true ili while:, gdje je simbol: ekvivalent operacije koja nedostaje u Korn shell-u i bash-u. #!/bin/ksh # beskrajna petlja while: do echo hello sleep 1 done

Do petlje

Ispod je jednostavan primjer korištenja do petlje. neka je i=100; do [ $i -le 0 ] ; do echo Odbrojavanje od 100 do 1, trenutna vrijednost $i; neka ja--; učinjeno

Vježbe: Testovi i petlje u skriptama

3. Razvijte skriptu koja će koristiti while petlju za brojanje od 3 do 7.

4. Razvijte skriptu koja će koristiti petlju do za odbrojavanje od 8 do 4.

5. Razvijte skriptu koja će brojati datoteke s nastavkom .txt u trenutnom direktoriju.

6. Upotrijebite naredbu if u stvorenoj skripti kako bi ispravno radila ako u trenutnom direktoriju nema datoteka s nastavkom .txt.

Ispravan postupak rješavanja praktičnog zadatka: provjere i petlje u skriptama

1. Razvijte skriptu koja će koristiti for petlju za brojanje od 3 do 7.

#!/bin/bash for i in 3 4 5 6 7 do echo Brojanje od 3 do 7, trenutna vrijednost $i gotovo

2. Razvijte skriptu koja će koristiti for petlju za brojanje od 1 do 17000.

Bash ljuska podržava for petlje, koje vam omogućuju ponavljanje nizova vrijednosti. To je ono što je osnovna struktura takvi ciklusi:

Za var na popisu do naredba dovršena
U svakoj iteraciji petlje, varijabla var bit će zapisana na sljedeću vrijednost iz popis. Stoga će prvi prolaz petlje koristiti prvu vrijednost s popisa. U drugom - drugi, i tako dalje - dok petlja ne dođe do posljednjeg elementa.

Ponavljanje jednostavnih vrijednosti

Možda je najjednostavniji primjer for petlje u bash skriptama iteracija preko popisa jednostavnih vrijednosti:

#!/bin/bash for var in first second third fourth fifth do echo Stavka $var dovršena
Rezultati ove skripte prikazani su u nastavku. Možete jasno vidjeti da varijabla $var sadrži elemente s popisa redom. To se događa sve dok ciklus ne dosegne posljednji od njih.


Jednostavna for petlja

Imajte na umu da varijabla $var zadržava svoju vrijednost pri izlasku iz petlje, njen sadržaj se može mijenjati, i općenito, možete raditi s njom kao sa svakom drugom varijablom.

Ponavljanje složenih vrijednosti

Popis koji se koristi za inicijalizaciju for petlje može sadržavati ne samo jednostavne nizove koji se sastoje od jedne riječi, već i cijele fraze koje sadrže nekoliko riječi i interpunkcijskih znakova. Na primjer, to bi moglo izgledati ovako:

#!/bin/bash for var in first "the second" "the third" "Ja ću to" do echo "This is: $var" done
Ovo se događa nakon što ova petlja prođe kroz popis. Kao što vidite, rezultat je sasvim očekivan.


Ponavljanje složenih vrijednosti
TNW-CUS-FMP - promo kod za 10% popusta na naše usluge, dostupan za aktivaciju u roku od 7 dana"

Pokretanje petlje s popisom dobivenim iz rezultata naredbe

Drugi način inicijalizacije for petlje je prosljeđivanje liste, koja je rezultat naredbe. Ovdje se koristi zamjena naredbi za njihovo izvršenje i dobivanje rezultata njihovog rada.

#!/bin/bash file="myfile" for var in $(cat $file) do echo " $var" done
Ovaj primjer koristi naredbu cat koja čita sadržaj datoteke. Rezultirajući popis vrijednosti prosljeđuje se u petlju i prikazuje na ekranu. Imajte na umu da datoteka kojoj pristupamo sadrži popis riječi odvojenih novim redovima; ne koriste se razmaci.


Petlja koja prolazi kroz sadržaj datoteke

Ovdje moramo uzeti u obzir da takav pristup, ako se očekuje line-by-line obrada podataka, neće funkcionirati za datoteku složenije strukture, čiji reci mogu sadržavati nekoliko riječi odvojenih razmacima. Petlja će obraditi pojedinačne riječi, a ne retke.

Što ako ovo uopće nije ono što vam treba?

Razdjelnici polja

Razlog za gornju značajku je poseban varijabla okoline, koji se zove IFS (Internal Field Separator) i omogućuje vam određivanje separatora polja. Prema zadanim postavkama, bash ljuska smatra sljedeće znakove separatorima polja:
  • Prostor
  • Tab znak
  • Znak za novi redak
Ako bash naiđe na bilo koji od ovih znakova u podacima, pretpostavlja se da mu prethodi sljedeća neovisna vrijednost na popisu.

Kako biste riješili problem, možete privremeno promijeniti varijablu okruženja IFS. Evo kako to učiniti u bash skripti, pod pretpostavkom da trebate samo novi redak kao razdjelnik polja:

IFS=$"\n"
Nakon što dodate ovu naredbu svojoj bash skripti, ona će raditi prema očekivanjima, ignorirajući razmake i kartice i tretirajući samo znakove novog retka kao razdjelnike polja.

#!/bin/bash file="/etc/passwd" IFS=$"\n" for var in $(cat $file) do echo " $var" done
Ako se ova skripta pokrene, ispisat će točno ono što se od nje traži, dajući, u svakoj iteraciji petlje, pristup sljedećem retku zapisanom u datoteci.


Redak po redak obilazak datoteke u for petlji

Razdjelnici mogu biti i drugi znakovi. Na primjer, iznad smo prikazali sadržaj /etc/passwd datoteke. Korisnički podaci u redovima su odvojeni dvotočkama. Ako trebate obraditi takve nizove u petlji, IFS se može konfigurirati ovako:

Prelaženje datoteka sadržanih u direktoriju

Jedna od najčešćih upotreba for petlji u bash skriptama je prelaženje datoteka smještenih u direktoriju i obrada tih datoteka.

Na primjer, evo kako ispisati datoteke i mape:

#!/bin/bash za datoteku u /home/likegeeks/* do if [ -d "$file" ] then echo "$file je direktorij" elif [ -f "$file" ] then echo "$file je datoteka" fi gotovo
Ako ste razumjeli prethodni materijal u ovoj seriji članaka, trebali biste razumjeti strukturu if-then konstrukcije, kao i kako razlikovati datoteku od mape. Ako vam je teško razumjeti gornji kôd, ponovno pročitajte ovaj materijal.

To je ono što će skripta ispisati.


Prikaz sadržaja mape

Obratite pozornost na to kako inicijaliziramo petlju, naime zamjenski znak"*" na kraju adrese mape. Ovaj se simbol može smatrati zamjenskim znakom koji znači: "sve datoteke s bilo kojim nazivima." omogućuje vam organiziranje automatska zamjena imena datoteka koja odgovaraju uzorku.

Kada testiramo uvjet u if naredbi, naziv varijable stavljamo u navodnike. To je učinjeno jer naziv datoteke ili mape može sadržavati razmake.

C-stil za petlje

Ako ste upoznati s programskim jezikom C, sintaksa za opisivanje bash for petlji može vam se činiti čudnom, budući da ste očito navikli opisivati ​​petlje na ovaj način:

Za (i = 0; i< 10; i++) { printf("number is %d\n", i); }
U bash skriptama možete koristiti for petlje, čiji opis izgleda vrlo slično petljama u stilu C, iako postoje neke razlike. Dijagram ciklusa s ovim pristupom izgleda ovako:

Za ((početna vrijednost varijable; uvjet za završetak petlje; promjena varijable))
U bashu se može napisati ovako:

Za ((a = 1; a< 10; a++))
Evo primjera rada:

#!/bin/bash for ((i=1; i<= 10; i++)) do echo "number is $i" done
Ovaj kod će ispisati popis brojeva od 1 do 10.

Looping u C stilu

while petlja

For konstrukcija nije jedini način organiziranja petlji u bash skriptama. Ovdje također možete koristiti while petlje. U takvoj petlji možete odrediti naredbu za provjeru određenog uvjeta i izvršavanje tijela petlje sve dok uvjet koji se testira ne vrati nulu ili signal za uspješan završetak određene operacije. Kada uvjet petlje vrati vrijednost različitu od nule, što znači pogrešku, petlja će se zaustaviti.

Ovdje je dijagram organizacije while petlji
dok naredba za provjeru stanja
čini
druge ekipe
učinjeno

Pogledajmo primjer skripte s ovakvom petljom:

#!/bin/bash var1=5 while [ $var1 -gt 0 ] do echo $var1 var1=$[ $var1 - 1 ] done
Na ulazu u petlju provjerava se da li je varijabla $var1 veća od nule. Ako je tako, izvršava se tijelo petlje u kojoj se jedan oduzima od vrijednosti varijable. To se događa u svakoj iteraciji, a mi ispisujemo vrijednost varijable na konzolu prije nego što se ona modificira. Čim $var1 dosegne vrijednost 0, petlja se zaustavlja.

Rezultat while petlje

Ako ne modificirate varijablu $var1, to će uzrokovati da skripta završi u beskonačnoj petlji.

Ugniježđene petlje

Možete koristiti bilo koje naredbe u tijelu petlje, uključujući pokretanje drugih petlji. Takve konstrukcije nazivaju se ugniježđene petlje:

#!/bin/bash for ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
Ispod je ono što će ova skripta ispisati. Kao što vidite, prvo se izvodi prva iteracija vanjske petlje, zatim tri iteracije unutarnje, nakon njenog završetka ponovno dolazi vanjska petlja, pa opet unutarnja.

Ugniježđene petlje

Obrada sadržaja datoteke

Najčešće se za obradu datoteka koriste ugniježđene petlje. Dakle, vanjska petlja ponavlja retke datoteke, a unutarnja već radi sa svakim retkom. Evo, na primjer, kako izgleda obrada datoteke /etc/passwd:

#!/bin/bash IFS=$"\n" za unos u $(cat /etc/passwd) do echo "Vrijednosti u $entry –" IFS=: za vrijednost u $entry do echo " $value" done učinjeno
U ovoj skripti postoje dvije petlje. Prvi prolazi kroz retke koristeći znak za novi red kao graničnik. Interni je zauzet raščlanjivanjem nizova čija su polja odvojena dvotočkama.

Obrada podataka datoteke

Ovaj se pristup može koristiti pri obradi CSV datoteka ili bilo kojih sličnih datoteka upisivanjem znaka razgraničenja u varijablu okoline IFS prema potrebi.

Upravljanje ciklusom

Možda ćete nakon ulaska u petlju trebati zaustaviti je kada varijabla petlje dosegne određenu vrijednost koja ne odgovara inicijalno navedenom uvjetu za završetak petlje. Hoće li u takvoj situaciji biti potrebno čekati normalan završetak ciklusa? Naravno da ne, au takvim slučajevima dobro će doći sljedeće dvije naredbe:
  • pauza
  • nastaviti

prekinuti naredbu

Ova naredba vam omogućuje da prekinete izvođenje petlje. Može se koristiti i za for i za while petlje:

#!/bin/bash za var1 u 1 2 3 4 5 6 7 8 9 10 do if [ $var1 -eq 5 ] then break fi echo "Number: $var1" done
Takva petlja, pod normalnim uvjetima, proći će kroz cijeli popis vrijednosti s popisa. Međutim, u našem slučaju, njegovo će se izvršenje prekinuti kada varijabla $var1 bude jednaka 5.

Rani izlazak iz for petlje

Ovdje je ista stvar, ali za while petlju:

#!/bin/bash var1=1 while [ $var1 -lt 10 ] do if [ $var1 -eq 5 ] then break fi echo "Iteracija: $var1" var1=$(($var1 + 1)) done
Naredba break, koja se izvršava kada $var1 dosegne 5, prekida petlju. Konzola će prikazati istu stvar kao u prethodnom primjeru.

naredba za nastavak

Kada se ova naredba susreće u tijelu petlje, trenutna iteracija završava ranije i započinje sljedeća, bez izlaska iz petlje. Pogledajmo naredbu continue u for petlji:

#!/bin/bash za ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
Kada je uvjet unutar petlje zadovoljen, odnosno kada je $var1 veći od 5 i manji od 10, ljuska izvršava naredbu za nastavak. To rezultira preskakanjem preostalih naredbi u tijelu petlje i prelaskom na sljedeću iteraciju.

Naredba za nastavak u for petlji

Obrada izlaza radi u petlji

Izlaz podataka iz petlje može se obraditi preusmjeravanjem izlaza ili prosljeđivanjem u cjevovod. To se postiže dodavanjem naredbi za obradu izlaza nakon izjave done.

Na primjer, umjesto da na ekranu prikazujete što je izlaz u petlji, možete sve to napisati u datoteku ili proslijediti negdje drugdje:

#!/bin/bash for ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt echo "gotovo."
Ljuska će stvoriti datoteku myfile.txt i preusmjeriti izlaz naredbe for u tu datoteku. Otvorimo datoteku i uvjerimo se da sadrži točno ono što očekujemo.

Preusmjeri izlaz petlje u datoteku

Primjer: Potražite izvršne datoteke

Iskoristimo ono što smo već pokrili i napišimo nešto korisno. Na primjer, ako trebate saznati koje su izvršne datoteke dostupne na sustavu, možete skenirati sve mape snimljene u varijabli okruženja PATH. Već imamo cijeli arsenal alata koji su nam potrebni za ovo, samo ih trebamo sastaviti:

#!/bin/bash IFS=: za mapu u $PATH do echo "$folder:" za datoteku u $folder/* do if [ -x $file ] then echo " $file" fi done done
Ova skripta, mala i jednostavna, omogućila nam je da dobijemo popis izvršnih datoteka pohranjenih u mapama iz PATH-a.

Traženje izvršnih datoteka u mapama iz varijable PATH

Rezultati

Danas smo razgovarali o for i while petljama u bash skriptama, kako ih pokrenuti i kako njima upravljati. Sada znate kako obraditi nizove s različitim graničnicima u petljama, znate kako preusmjeriti izlaz podataka u petljama u datoteke, kako pregledati i analizirati sadržaj direktorija.

Ako pretpostavimo da ste programer bash skripti koji o njima zna samo ono što je navedeno u prvom dijelu ove serije članaka, te u ovom drugom, onda već možete napisati nešto korisno. Pred nama je treći dio, nakon čijeg razumijevanja ćete naučiti kako proslijediti parametre i prekidače naredbenog retka u bash skripte i što učiniti sa svim tim.

Kratak opis razlika u vrstama petlji:

for - izvršit će akciju sve dok ima objekata za izvršenje (na primjer, čitanje toka iz stdin-a, datoteke ili funkcije);
dok - izvodi radnju do stanje je istina;
do - izvršavat će se sve dok stanje neće postati istina, tj. za sada je lažno .

FOR petlja

Razmotrimo ovu verziju skripte s petljom:

$ cat loop.sh #!/bin/bash za varijablu u `ls -1` do echo "$variable" done

Sintaksa je vrlo jednostavna i prilično jasno prikazana u primjeru:

for (pokretanje petlje) varijabla (deklarirati varijablu na kojoj ćemo izvoditi radnje) in (pošalji tijek u petlju) `ls -1` (naredba koju treba izvršiti i proslijediti varijabli $variable). Do i done su “tijelo” petlje, unutar kojeg će se izvršiti glavne akcije nad primljenim podacima, a echo “$varijabla” je stvarna radnja koju izvodi petlja.

Sada malo promijenimo primjer i umjesto eksplicitnog navođenja naredbe koristit ćemo drugu varijablu:

$ cat loop.sh #!/bin/bash ls=`ls -1` za varijablu u $ls do echo "$variable" done

Sada se naredba ls -1 prosljeđuje u zasebnoj varijabli, što vam omogućuje fleksibilniji rad s petljom. Umjesto varijable u petlji, također možete koristiti funkciju:

$ cat loop.sh #!/bin/bash lsl () ( ls -1 ) za varijablu u `lsl` do echo "$variable" done

Glavni uvjet for petlje je da će se izvršavati sve dok naredba koja joj je proslijeđena sadrži objekte za akciju. Na temelju gornjeg primjera - sve dok ls -1 ima datoteke za prikaz - petlja će ih proslijediti varijabli i izvršiti "tijelo petlje". Čim popis datoteka u direktoriju završi, petlja će završiti svoje izvršenje.

Učinimo primjer malo kompliciranijim.

Direktorij sadrži popis datoteka:

$ ls -1 datoteka1 datoteka2 datoteka3 datoteka4 datoteka5 petlja.sh nofile1 nofile2 nofile3 nofile4 nofile5

Od njih trebamo odabrati samo one koji nemaju riječ " Ne«:

$ cat loop.sh #!/bin/bash lsl=`ls -1` za varijablu u $lsl do echo "$variable" | grep -v "ne" gotovo $ ./loop.sh datoteka1 datoteka2 datoteka3 datoteka4 datoteka5 petlja.sh

Također možete koristiti uvjetne izraze u petlji ( uvjetni izrazi) […] za provjeru uvjeta i naredbu break za prekid petlje ako se uvjet pokrene.

Razmotrite ovaj primjer:

$ cat loop.sh #!/bin/bash lsl=`ls -1` za varijablu u $lsl do if [ $varijabla != "loop.sh" ] then echo "$varijabla" | grep -v "no" else break fi gotovo

Petlja će se nastaviti sve dok se ne naiđe na datoteku loop.sh. Čim izvođenje petlje dođe do ove datoteke, petlja će biti prekinuta naredbom break:

$ ./loop.sh datoteka1 datoteka2 datoteka3 datoteka4 datoteka5

Drugi primjer je korištenje aritmetičkih operacija neposredno prije izvođenja tijela petlje:

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

Ovdje postavljamo tri kontrolne naredbe - count=1, kontrolni uvjet - dok je count manji od 11 i naredbu za izvršenje - count +1:

WHILE i UNTIL petlje

Jednostavan primjer koji jasno pokazuje kako funkcionira while petlja:

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

Postavljamo varijablu $count na nulu, a zatim pokrećemo petlju whi le s uvjetom "dok je $count manji od deset, izvrši petlju." U tijelu petlje koju izvršavamo postfiksni priraštaj+1 varijabli $count i rezultat se ispisuje u stdout.

Rezultat izvršenja:

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

Čim je vrijednost varijable $count postala 10, petlja se zaustavila.

Dobar primjer "beskonačne" petlje koja pokazuje kako while funkcionira:

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

Dok petlja radi slično, ali u suprotnom smjeru:

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

Ovdje postavljamo sličan uvjet, ali umjesto "dok je varijabla manja od 10", navodimo "dok varijabla ne postane veća od 10". Rezultat izvršenja:

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

Ako se gornji primjer "beskonačne petlje" izvrši korištenjem until, neće ništa ispisati, za razliku od while:

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

jer " stanje"izvorno" pravi"— tijelo petlje se neće izvršiti.

Baš kao u for petlji, možete koristiti funkcije u while i until. Na primjer, petlja iz stvarne skripte koja provjerava status poslužitelja Mačak(PID se uzima iz sustava SLES, može se razlikovati u drugim sustavima), malo pojednostavljena verzija:

$ cat loop.sh #!/bin/bash check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) dok check_tomcat_status do if [ -n "$ RUN" ] then printf "UPOZORENJE: Tomcat i dalje radi s PID $RUN." else printf "Tomcat zaustavljen, nastavlja se...nn" break fi gotovo

Rezultat izvršenja:

$ ./loop.sh UPOZORENJE: Tomcat i dalje radi s PID-om 14435 26548. UPOZORENJE: Tomcat i dalje radi s PID-om 14435 26548. UPOZORENJE: Tomcat i dalje radi s PID-om 14435 26548. UPOZORENJE: Tomcat i dalje radi s PID-om 14435 26548. UPOZORENJE: Tomcat i dalje radi s PID-om 14435 26548.UPOZORENJE: Tomcat i dalje radi s PID-om 14435 26548.UPOZORENJE: Tomcat i dalje radi s PID-om 14435 26548.UPOZORENJE: Tomcat i dalje radi s PID-om 14435

Puna verzija:

Check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) while check_tomcat_status; do if [ -n "$RUN" ] then printf "UPOZORENJE: Tomcat još uvijek radi s PID $RUN. Zaustaviti ga? " answer "Zaustavljanje Tomcata..." "Nastavak instalacije..." && $CATALINA_HOME/bin/shutdown .sh 2&>1 /dev/null || break sleep 2 if [ -n "$RUN" ] then printf "Tomcat i dalje radi. Ubiti ga? " answer "Ubijanje Tomcata..." "Nastavak instalacije...n" && kill $RUN || break sleep 2 fi else printf "Tomcat zaustavljen, nastavlja se...nn" break fi done

Funkcija odgovora opisana je u članku, ali ovdje se koristi malo poboljšana verzija:

Answer () ( while read response; do echo case $response in |) printf "$1n" return 0 break ;; |) printf "$2n" vrati 1 prijelom ;; *) printf "Molimo, unesite Y(yes) ili N(ne)!" esac done )

Ovdje je bilo moguće koristiti i while i until - ali ne i for petlju, budući da bi for radio jednom (primio PID i završio).

Petlje su vrlo zgodna stvar pri pisanju bilo kakvih programa ili skripti, čak i neophodna. Omogućuju nam da izvršimo određeni dio koda određeni broj puta. Naravno, bash ima nekoliko vrsta petlji. Opisat ćemo cikluse za u, za, dok, dok. Iako se for in i for smatraju različitim sintaksama iste izjave, po mom mišljenju one se razlikuju jedna od druge više nego while od do.

Petlja s brojačem za in:

Ciklus za u Ovo je petlja s brojačem. Blok koda koji se nalazi u tijelu petlje ponavlja se onoliko puta koliko ima vrijednosti sadržanih u popisu operatora for in, a sa svakim ponavljanjem, varijabla brojača (ovdje se zove var, ali naravno možete ga zvati kako god želite) ima vrijednost sljedećeg elementa liste.
Ako je ključna riječ do u istom retku kao i riječ for, tada nakon popisa argumenata (ispred do) morate staviti točku i zarez.
Svaki od elemenata<список>može sadržavati više argumenata. Ovo je korisno pri obradi grupa parametara. U ovom slučaju, za prisilno analiziranje svakog od argumenata u<списке>, morate koristiti postavljenu uputu
Možete koristiti varijablu kao popis u for petlji.
U<списке>Petlja for može koristiti nazive datoteka, koji zauzvrat mogu sadržavati zamjenske znakove. Ovo može biti vrlo korisno kada radite s velikim brojem datoteka.
Ako<список>nije naveden u for petlji, tada se kao njega koristi varijabla $@ - popis argumenata naredbenog retka.
Kada stvarate popis argumenata, možete koristiti zamjenu naredbe u for petlji.
Izlaz petlje može se preusmjeriti sa stdout-a na datoteku ili negdje drugdje (možete saznati više o tome ako pogledate I/O preusmjeravanje).

Sintaksa:
za var in<список>
čini
<выполняемые команды>
učinjeno

Primjer:
za imena u ime1 ime2 ime3 ime4
čini
echo $names
učinjeno

Operator petlje za ima drugi način pisanja - vrlo sličan sintaksi operatora for u jeziku C. U ovom slučaju, prilikom inicijalizacije brojača postavljaju se početne vrijednosti varijabli ili jedne varijable i nakon svakog prolaza petlje uvjet je označen, ako provjera vrati true, tada počinje sljedeći prolaz petlje. U bloku<приращение счётчиков>vrijednost naše varijable brojača mora se nužno promijeniti (ne nužno prema gore) tako da prilikom provjere uvjeta prije ili kasnije dobijemo vrijednost false, inače petlja nikada neće završiti. Vrlo zgodna i što je najvažnije poznata opcija ako bilo koju operaciju treba ponoviti određeni broj puta.

Sa sličnom sintaksom:
za ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
čini
<выполняемые команды>
učinjeno

Primjer:
za ((var=1; var<= LIMIT ; var++))
čini
odjek $var
učinjeno

while petlja:

Ovo je prilično jednostavna konstrukcija koja provjerava stanje iza operatora dok i ako je ovaj uvjet istinit, izvršava blok naredbi koji se nalazi između riječi do i done i zatim ponovno nastavlja s provjerom uvjeta. Ako provjera vrati false, ciklus završava i počinju se izvršavati sljedeće naredbe: učinjeno. To je imperativ osigurati<проверка условия>ovisi o kodu koji se izvodi u petlji; inače, ako se rezultat provjere ne promijeni, dobit ćete beskonačnu petlju.
Standardni ulazni uređaj za while petlju može se preusmjeriti na datoteku pomoću naredbe za preusmjeravanje< в конце цикла.

Sintaksa:
dok<Проверка условия>
čini
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
učinjeno

Primjer:
dok [ $var0 -eq 100 ]
čini
odjek $var
var++
učinjeno

Operater dok može imati nekoliko uvjeta. Ali samo posljednji od njih određuje mogućnost nastavka ciklusa. U tom će slučaju sintaksa operatora petlje biti drugačija od uobičajene.
Sintaksa(Ponavljam još jednom da samo posljednji uvjet utječe na izvođenje petlje) :
dok
<условие1>
<условие2>

<условиеN>
čini
<выполняемые команды - тело цикла>
učinjeno

Do petlje:

Operater do je vrlo sličan while, također procjenjuje uvjet, ali izvršava tijelo petlje ako je rezultat izračuna lažan. Možda se čini neuobičajenim, ali dok procjenjuje stanje prije prvog prolaza petlje, kao while, a ne nakon njega. Kao i kod for/in petlji, kada stavljate ključnu riječ do u isti redak s deklaracijom petlje, morate umetnuti znak ";". prije učiniti.
Kao iu prethodnom slučaju, važno je zapamtiti da uvjet mora ovisiti o operacijama u tijelu petlje, inače naša skripta nikada neće završiti.

Sintaksa:
do<Проверка условия>
čini
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
učinjeno

Primjer:
until [ $var0 -gt 100] # Uvjet se provjerava na početku iteracije.
čini
odjek $var
var--
učinjeno

To je vjerojatno dovoljno za sada. :)

  • leđa
  • Naprijed

Novi članci:

  • Otkrivanje mreže ne uključuje se u sustavu Windows 7/8/2008/2012
  • Pogreška: Ova se aplikacija nije uspjela pokrenuti jer nije mogla pronaći ili učitati dodatak Qt platforme "windows".
  • Konfiguriranje automatskog ponovnog pokretanja radnih procesa rphost.exe na poslužitelju 1C 8.3
  • Kako smanjiti veličinu dnevnika transakcija (.ldf) u MS SQL 2008/20012

    MS SQL, kao i svaki pristojan industrijski DBMS, zajedno s bazom podataka, čuva zapise transakcija koji vam omogućuju vraćanje stanja...

0 Meeran Bala-Kumaran

Stvarno pokušavam shvatiti zašto ova petlja while nikada ne završava, kada petlja započne moja LOC varijabla postavljena je na Testing/ što je direktorij koji sam stvorio za testiranje ovog programa i ima sljedeći izgled:

Želim da petlja završi nakon što se na sve direktorije primijeni funkcija "count".
Evo što sam pokušao;

Provjerio sam funkciju brojanja i ne stvara beskonačnu petlju

Pokušao sam pokrenuti algoritam ručno

PARSE=1 LOC=$LOC/ count AVAILABLEDIR=$(ls $LOC -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") dok [ $PARSE = "1" ] uradi ako [[ $(AVAILABLEDIR[@]) == "" ]]; zatim PARSE=0 fi DIRBASE=$LOC za a u $(AVAILABLEDIR[@]); do LOC="$(DIRBASE)$(a)" LOCLIST="$LOCLIST $LOC" count done for a in $(LOCLIST[@]); do TMPAVAILABLEDIR=$(ls $a -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") PREPEND=$a if [[ $(TMPAVAILABLEDIR[@]) == "" ] ]; zatim nastavite fi za a u $(TMPAVAILABLEDIR[@]); do TMPAVAILABLEDIR2="$TMPAVAILABLEDIR2 $(PREPEND[@])$(a)" gotovo NEWAVAILABLEDIR="$NEWAVAILABLEDIR $TMPAVAILABLEDIR2" gotovo AVAILABLEDIR=$NEWAVAILABLEDIR NEWAVAILABLEDIR="" LOC="" gotovo

Stvarno se mučim i bilo kakav doprinos bio bih jako cijenjen, pokušavao sam ovo shvatiti posljednja dva sata.

bash beskonačna petlja

4 odgovora

Trebali biste pokušati pokrenuti skriptu s argumentom -x ili je napisati u prvom redu:

#!/bin/bash -x

Tada vam govori sve što radi.

U ovom slučaju možete primijetiti dvije pogreške:

    Nikada ne učitavate ponovno TMPAVAILABLEDIR2

    Također radite ls na običnim datotekama.

Ako stvarno morate izbjegavati rekurziju, pokušajte ovo, potpuno bez rekurzije:

#!/bin/bash count() ( echo counting "$1" ) todo=(Testiranje) dok testirate $(#todo[@]) != 0 do doit=("$(todo[@])") todo= () za dir u "$(doit[@])" do za unos u "$dir"/* # ako je dir prazan, ovo prikazuje unos pod nazivom "*" do test -e "$entry" || nastaviti # preskočiti unos "*" praznog dir count "$entry" test -d "$entry" || nastavi todo+=("$entry") učinjeno učinjeno učinjeno

Međutim, molim vas recite mi zašto ne možete koristiti rekurziju? Je li to neka vrsta alergije? Zavjet? Postoje li lokalni zakoni protiv rekurzivnog softvera tamo gdje živite?

Napisali ste da želite izvršiti "prebrojavanje" na svim rezovima. Provjerite opcije pretraživanja:

Pronađite $LOC -tip d | dok čitam dir; do cd $LOC cd $(dir) count done

ili kraće (kada vaš brojač funkcija uzima direktorij kao parametar 1)

Pronađite $LOC -tip d | xargs count

Sada vidim da ne želite koristiti find ili ls -R (rekurzivna funkcija). Tada biste trebali napraviti vlastitu rekurzivnu funkciju poput

Funkcija parseDir ( ls -d */ $1 | tijekom čitanja direktorija; brojati parseDir $1/$dir gotovo )

Nemam pojma hoće li ovo funkcionirati, ali to je zanimljivo pitanje o kojem nisam mogao prestati razmišljati. Sretno

Dok je istina ; učiniti za riječ u "$(echo *)" ; učiniti if [[ -d "$word" ]] ; zatim d[$((i++))]="$PWD"/"$word" elif [[ -f "$word" ]] ;zatim f[$((j++))]="$PWD"/"$ riječ" fi gotovo [[ $k -gt $i ]] && cd .. cd "$d[$((k++))]" || prekid učinjen