Acasă - Laptop-uri
Bash while buclă infinită. Buclă while infinită în scriptul BASH

Autor: Paul Cobbaut
Data publicării: 16 octombrie 2014
Traducere: A. Panin
Data traducerii: 21 decembrie 2014

Capitolul 22. Bucle în Scripturi

comanda de testare

Comanda test vă permite să determinați dacă o expresie este adevărată sau falsă. Să începem prin a testa dacă valoarea întreagă 10 este mai mare decât valoarea întreagă 55. $ test 10 -gt 55 ; eco $? 1 $

Comanda test returnează 1 dacă expresia este falsă. Și, după cum veți vedea în exemplul următor, comanda de test va returna 0 dacă expresia este evaluată la adevărat.

$ test 56 -gt 55 ; eco $? 0 USD

Dacă sunteți mai confortabil să lucrați cu șirurile true și false, puteți utiliza comanda de testare așa cum se arată mai jos.

$ test 56 -gt 55 && echo true || echo false true $ test 6 -gt 55 && echo true || ecou fals fals Comanda de testare poate fi înlocuită și cu paranteze drepte, așa că comenzile din exemplul de mai jos sunt exact aceleași cu comenzile din exemplul de mai sus. implementarea diferitelor controale.< $bar ] Будет ли строка abc расположена выше значения переменной $bar в списке после сортировки? [ -f foo ] Является ли foo обычным файлом? [ -r bar ] Является ли bar читаемым файлом? [ foo -nt bar ] Новее ли файл foo файла bar ? [ -o nounset ] Активирован ли параметр командной оболочки nounset ?

[ -d foo ] Există directorul foo? [ -e bar ] Există fișierul bar? [ "/etc" = $PWD ] Este /etc echivalent cu valoarea $PWD? [ $1 != "secret" ] Valoarea primului parametru de script este diferită de șirul secret? [ 55 -lt $bar ] Este valoarea întreagă 55 mai mică decât valoarea lui $bar? [ $foo -ge 1000 ] Este valoarea lui $foo mai mare sau egală cu valoarea întregului 1000? ["abc"

Operatorii de testare pot fi combinați cu operatori corespunzători operatorilor logici „ȘI” și „SAU”.

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 || ecou fals adevărat

Salt condiționat dacă altfel Construcția if then else are scopul de a selecta o opțiune de cod. Dacă o anumită condiție este adevărată, un cod va fi executat, în caz contrar, un alt cod va fi executat. Exemplul de mai jos verifică existența unui fișier, după care, dacă se confirmă presupunerea existenței fișierului, se afișează un mesaj corespunzător.#!/bin/bash dacă [ -f isit.txt ] atunci ecou fișierul isit.txt există! altfel fișierul echo isit.txt nu a fost găsit! fi

În cazul în care economisim

acest cod script într-un fișier numit „choice”, acesta poate fi executat în același mod.$ ./choice fișier isit.txt nu a fost găsit! $ atingeți isit.txt $ ./choice fișier isit.txt există! $

Salt condiționat dacă atunci elif

Puteți posta un nou operator

salt condiționat

Un script complet similar cu cel prezentat mai sus poate fi creat fără a utiliza un shell de comandă încorporat, folosind declarația shell bash pentru o gamă de valori (de la valoare..la valoare).

#!/bin/bash pentru contor în (1..20) face ecou numărare de la 1 la 20, valoarea curentă $counter sleep 1 terminat ÎN acest ciclu for folosește un mecanism pentru căutarea fișierelor după model (implementat ca parte a mecanismului de extindere a comenzii). Dacă instrucțiunile de mai sus sunt postate direct în linie de comandă

, va funcționa similar.

kahlan@solexp11$ ls count.ksh go.ksh kahlan@solexp11$ pentru fișierul în *.ksh ; do cp $file $file.backup ; gata kahlan@solexp11$ ls count.ksh count.ksh.backup go.ksh go.ksh.backup

buclă while

Mai jos este un exemplu simplu de utilizare a unei bucle while.

i=100; în timp ce [ $i -ge 0 ] ; do echo Numărătoarea inversă de la 100 la 0, valoarea curentă $i;

lasa i--; făcut

Buclele infinite pot fi implementate folosind declarații while true sau while:, unde simbolul: este echivalentul operației lipsă din shell-ul Korn și bash. #!/bin/ksh # buclă fără sfârșit while: do echo hello sleep 1 done Până la buclă

Mai jos este un exemplu simplu de utilizare a unei bucle până.

fie i=100; până la [ $i -le 0 ] ; face eco Numărătoare inversă de la 100 la 1, valoarea curentă $i;

lasa i--; făcut

Practică: teste și bucle în scripturi

3. Dezvoltați un script care va folosi

buclă while

sa numere de la 3 la 7.

4. Dezvoltați un script care va folosi o buclă până pentru a număra invers de la 8 la 4.

5. Dezvoltați un script care va număra fișierele cu extensia .txt în directorul curent.
În fiecare iterație a buclei, următoarea valoare din listă va fi scrisă în variabila var. Prin urmare, prima trecere a buclei va folosi prima valoare din listă. În al doilea - al doilea și așa mai departe - până când bucla ajunge la ultimul element.

Iterarea peste valori simple

Poate cel mai simplu exemplu de buclă for în scripturile bash este repetarea unei liste de valori simple:

#!/bin/bash pentru var în prima secundă a treia a patra a cincea face echo Elementul $var terminat
Rezultatele acestui script sunt prezentate mai jos. Puteți vedea clar că variabila $var conține elemente din listă secvenţial. Acest lucru se întâmplă până când ciclul ajunge la ultimul dintre ele.


Simplu pentru buclă

Vă rugăm să rețineți că variabila $var își păstrează valoarea la ieșirea din buclă, conținutul ei poate fi schimbat și, în general, puteți lucra cu ea ca orice altă variabilă.

Iterarea peste valori complexe

Lista folosită pentru a inițializa bucla for poate conține nu numai șiruri simple formate dintr-un cuvânt, ci și fraze întregi care conțin mai multe cuvinte și semne de punctuație. De exemplu, ar putea arăta astfel:

#!/bin/bash pentru var în primul „al doilea” „al treilea” „O voi face” do echo „Acesta este: $var” gata
Acesta este ceea ce se întâmplă după ce această buclă trece prin listă. După cum puteți vedea, rezultatul este destul de așteptat.


Iterarea peste valori complexe
TNW-CUS-FMP - cod promoțional pentru o reducere de 10% la serviciile noastre, disponibil pentru activare în 7 zile"

Inițializarea unei bucle cu o listă obținută din rezultatele comenzii

O altă modalitate de a inițializa o buclă for este să îi transmiteți o listă, care este rezultatul unei comenzi. Aici înlocuirea comenzilor este folosită pentru a le executa și a obține rezultatele muncii lor.

#!/bin/bash file="myfile" pentru var în $(cat $file) face echo " $var" gata
Acest exemplu folosește comanda cat, care citește conținutul unui fișier. Lista de valori rezultată este trecută în buclă și afișată pe ecran. Vă rugăm să rețineți că fișierul pe care îl accesăm conține o listă de cuvinte separate prin linii noi, nu sunt folosite spații.


O buclă care parcurge conținutul unui fișier

Aici trebuie să ținem cont de faptul că o astfel de abordare, dacă se preconizează procesarea datelor linie cu linie, nu va funcționa pentru un fișier mai mare decât structura complexa, ale căror rânduri pot conține mai multe cuvinte separate prin spații. Bucla va procesa cuvinte individuale, nu linii.

Dacă nu este deloc ceea ce ai nevoie?

Separatoare de câmp

Motivul caracteristicii de mai sus este specialul variabila de mediu, care se numește IFS (Internal Field Separator) și vă permite să specificați separatori de câmp. În mod implicit, shell-ul bash consideră următoarele caractere separatoare de câmp:
  • Spaţiu
  • Caracter tabulator
  • Caracter de avans de linie
Dacă bash întâlnește oricare dintre aceste caractere în date, se presupune că este precedat de următoarea valoare independentă din listă.

Pentru a rezolva problema, puteți schimba temporar variabila de mediu IFS. Iată cum să o faceți într-un script bash, presupunând că aveți nevoie doar de o linie nouă ca separator de câmp:

IFS=$"\n"
Odată ce adăugați această comandă la scriptul dvs. bash, va funcționa conform așteptărilor, ignorând spațiile și tabulatorii și tratând doar caracterele newline ca separatori de câmp.

#!/bin/bash file="/etc/passwd" IFS=$"\n" pentru var în $(cat $fișier) do echo " $var" gata
Dacă acest script este rulat, va scoate exact ceea ce i se cere, oferind, în fiecare iterație a buclei, acces la următoarea linie scrisă în fișier.


Parcurgerea linie cu linie a unui fișier într-o buclă for

Separatorii pot fi și alte personaje. De exemplu, mai sus am afișat conținutul fișierului /etc/passwd. Datele utilizatorului pe linii sunt separate prin două puncte. Dacă trebuie să procesați astfel de șiruri într-o buclă, IFS poate fi configurat astfel:

Parcurgerea fișierelor conținute într-un director

Una dintre cele mai frecvente utilizări ale buclelor for în scripturile bash este să traverseze fișierele situate într-un director și să proceseze acele fișiere.

De exemplu, iată cum să enumerați fișierele și folderele:

#!/bin/bash pentru fișierul din /home/likegeeks/* do if [ -d "$fișier" ] apoi echo "$fișierul este un director" elif [ -f "$fișier" ] apoi echo "$fișierul este un fișier" fi terminat
Dacă ați înțeles materialul anterior din această serie de articole, ar trebui să înțelegeți structura construcției dacă-atunci, precum și cum să distingeți un fișier de un folder. Dacă vă este greu să înțelegeți codul de mai sus, recitiți acest material.

Acesta este ceea ce va scoate scriptul.


Afișarea conținutului unui folder

Observați cum inițializam bucla, și anume wildcardul „*” la sfârșitul adresei folderului. Acest simbol poate fi considerat un wildcard care înseamnă: „toate fișierele cu orice nume”. vă permite să vă organizați înlocuire automată nume de fișiere care se potrivesc cu modelul.

Când testăm o condiție într-o instrucțiune if, includem numele variabilei între ghilimele. Acest lucru se face deoarece numele fișierului sau folderului poate conține spații.

C-style pentru bucle

Dacă sunteți familiarizat cu limbajul de programare C, sintaxa pentru descrierea buclelor bash for vă poate părea ciudată, deoarece sunteți, evident, obișnuit să descrieți buclele astfel:

Pentru (i = 0; i< 10; i++) { printf("number is %d\n", i); }
În scripturile bash puteți folosi buclele for, a căror descriere arată foarte asemănătoare cu buclele în stil C, deși există unele diferențe. Diagrama ciclului cu această abordare arată astfel:

Pentru ((valoarea inițială a variabilei; condiția pentru încheierea buclei; schimbarea variabilei))
În bash se poate scrie așa:

Pentru ((a = 1; a< 10; a++))
Iată un exemplu de lucru:

#!/bin/bash pentru ((i=1; i<= 10; i++)) do echo "number is $i" done
Acest cod va scoate o listă de numere de la 1 la 10.

Buclă în stil C

buclă while

Construcția for nu este singura modalitate de a organiza buclele în scripturile bash. Puteți utiliza și buclele while aici. Într-o astfel de buclă, puteți specifica o comandă pentru a verifica o anumită condiție și a executa corpul buclei până când condiția testată returnează zero, sau un semnal pentru finalizarea cu succes a unei anumite operațiuni. Când condiția buclei returnează o valoare diferită de zero, ceea ce înseamnă o eroare, bucla se va opri.

Iată o diagramă a organizării buclelor while
în timp ce comanda de verificare a stării
do
alte echipe
făcut

Să aruncăm o privire la un exemplu de script cu o buclă ca aceasta:

#!/bin/bash var1=5 în timp ce [ $var1 -gt 0 ] face eco $var1 var1=$[ $var1 - 1 ] gata
La intrarea în buclă, se verifică dacă variabila $var1 este mai mare decât zero. Dacă da, se execută corpul buclei, în care se scade unul din valoarea variabilei. Acest lucru se întâmplă în fiecare iterație și imprimăm valoarea variabilei pe consolă înainte ca aceasta să fie modificată. De îndată ce $var1 atinge valoarea 0, bucla se oprește.

Rezultatul buclei while

Dacă nu modificați variabila $var1, acest lucru va face ca scriptul să ajungă într-o buclă infinită.

Bucle imbricate

Puteți utiliza orice comenzi din corpul buclei, inclusiv lansarea altor bucle. Astfel de construcții se numesc bucle imbricate:

#!/bin/bash pentru ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
Mai jos este ceea ce va afișa acest script. După cum puteți vedea, mai întâi se execută prima iterație a buclei exterioare, apoi trei iterații a celei interioare, după finalizarea acesteia intră din nou în joc bucla exterioară, apoi din nou cea interioară.

Bucle imbricate

Procesarea conținutului fișierului

Cel mai adesea, buclele imbricate sunt folosite pentru a procesa fișierele. Deci, bucla exterioară iterează peste liniile fișierului, iar cea interioară lucrează deja cu fiecare linie. Iată, de exemplu, cum arată procesarea fișierului /etc/passwd:

#!/bin/bash IFS=$"\n" pentru intrarea în $(cat /etc/passwd) face ecou "Valori în $entry –" IFS=: pentru valoarea în $entry face eco "$valoare" gata făcut
Există două bucle în acest script. Primul parcurge liniile folosind caracterul newline ca delimitator. Cel intern este ocupat cu analizarea șirurilor de caractere ale căror câmpuri sunt separate prin două puncte.

Procesarea datelor fișierului

Această abordare poate fi utilizată la procesarea fișierelor CSV sau a oricăror fișiere similare, prin scrierea caracterului delimitator în variabila de mediu IFS, după cum este necesar.

Managementul ciclului

Poate că, după intrarea în buclă, va trebui să o opriți atunci când variabila buclă atinge o anumită valoare care nu corespunde condiției specificate inițial pentru încheierea buclei. Într-o astfel de situație, va fi necesar să așteptăm finalizarea normală a ciclului? Bineînțeles că nu, și în astfel de cazuri următoarele două comenzi vor fi utile:
  • pauză
  • continua

comanda pauză

Această comandă vă permite să întrerupeți execuția unei bucle. Poate fi folosit atât pentru bucle for și while:

#!/bin/bash pentru var1 în 1 2 3 4 5 6 7 8 9 10 do if [ $var1 -eq 5 ] apoi break fi echo "Number: $var1" done
O astfel de buclă, în condiții normale, va trece prin întreaga listă de valori din listă. Totuși, în cazul nostru, execuția sa va fi întreruptă atunci când variabila $var1 este egală cu 5.

Ieșirea devreme dintr-o buclă for

Iată același lucru, dar pentru bucla while:

#!/bin/bash var1=1 în timp ce [ $var1 -lt 10 ] do if [ $var1 -eq 5 ] apoi break fi echo "Iteration: $var1" var1=$(($var1 + 1)) done
Comanda break, executată când $var1 ajunge la 5, întrerupe bucla. Consola va afișa același lucru ca în exemplul anterior.

continua comanda

Când această comandă este întâlnită în corpul buclei, iterația curentă se termină devreme și începe următoarea, fără a ieși din buclă. Să ne uităm la comanda continue într-o buclă for:

#!/bin/bash pentru ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
Când condiția din interiorul buclei este îndeplinită, adică atunci când $var1 este mai mare de 5 și mai mic de 10, shell-ul execută comanda continue. Acest lucru duce la omiterea comenzilor rămase în corpul buclei și trecerea la următoarea iterație.

Comanda continue într-o buclă for

Procesarea ieșirii rulează într-o buclă

Ieșirea datelor dintr-o buclă poate fi procesată fie prin redirecționarea ieșirii, fie prin trecerea acesteia către o conductă. Acest lucru se face prin adăugarea comenzilor de procesare a ieșirii după instrucțiunea done.

De exemplu, în loc să afișați pe ecran ceea ce este scos într-o buclă, puteți scrie totul într-un fișier sau îl puteți transmite în altă parte:

#!/bin/bash pentru ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt ecou „terminat”.
Shell-ul va crea fișierul myfile.txt și va redirecționa ieșirea instrucțiunii for către acel fișier. Să deschidem fișierul și să ne asigurăm că conține exact ceea ce ne așteptăm.

Redirecționați ieșirea buclei către fișier

Exemplu: Căutați fișiere executabile

Să folosim ceea ce am tratat deja și să scriem ceva util. De exemplu, dacă trebuie să aflați ce fișiere executabile sunt disponibile pe sistem, puteți scana toate folderele înregistrate în variabila de mediu PATH. Avem deja întregul arsenal de instrumente de care avem nevoie pentru asta, trebuie doar să le punem laolaltă:

#!/bin/bash IFS=: pentru folderul din $PATH, ecou „$folder:” pentru fișierul din $folder/* face if [ -x $file ] apoi echo „$file” fi gata
Acest script, mic și simplu, ne-a permis să obținem o listă de fișiere executabile stocate în foldere din PATH.

Căutarea fișierelor executabile în foldere din variabila PATH

Rezultate

Astăzi am vorbit despre buclele for și while în scripturile bash, cum să le rulăm și cum să le gestionăm. Acum știi cum să procesezi șiruri cu diferiți delimitatori în bucle, știi cum să redirecționezi datele de ieșire în bucle către fișiere, cum să vezi și să analizezi conținutul directoarelor.

Dacă presupunem că sunteți un dezvoltator de scripturi bash care știe despre ele doar ceea ce este menționat în prima parte a acestei serii de articole și în această a doua, atunci puteți deja să scrieți ceva util. Urmează a treia parte, după ce ați înțeles care veți învăța cum să treceți parametrii și comutatoarele din linia de comandă la scripturi bash și ce să faceți cu toate acestea.

O scurtă descriere a diferenței dintre tipurile de bucle:

for - va efectua o acțiune atâta timp cât există obiecte de executat (de exemplu, citirea unui flux din stdin, un fișier sau o funcție);
în timp ce - execută acţiunea până când stare este adevărat;
până când - se va executa atâta timp cât stare nu va deveni adevărat, adică deocamdata este fals.

FOR Loop

Luați în considerare această versiune a scriptului cu o buclă:

$ cat loop.sh #!/bin/bash pentru variabila în `ls -1` do echo "$variable" gata

Sintaxa este foarte simplă și este arătată destul de clar în exemplu:

for (începe bucla) variabilă (declară o variabilă asupra căreia vom efectua acțiuni) în (trimite un flux în buclă) `ls -1` (comandă care urmează să fie executată și transmisă variabilei $variabile). Do și done sunt „corpul” buclei, în cadrul căruia principalele acțiuni vor fi efectuate asupra datelor primite, iar echo „$variable” este acțiunea reală efectuată de buclă.

Acum să schimbăm puțin exemplul și, în loc să specificăm în mod explicit comanda, vom folosi a doua variabilă:

$ cat loop.sh #!/bin/bash ls=`ls -1` pentru variabila din $ls do echo "$variable" gata

Acum comanda ls -1 este transmisă într-o variabilă separată, ceea ce vă permite să lucrați cu bucla mai flexibil. În loc de o variabilă într-o buclă, puteți utiliza și o funcție:

$ cat loop.sh #!/bin/bash lsl () ( ls -1 ) pentru variabila din `lsl` do echo "$variable" done

Condiția principală a buclei for este ca aceasta să fie executată atâta timp cât comanda transmisă acesteia conține obiecte pentru acțiune. Pe baza exemplului de mai sus - atâta timp cât ls -1 are fișiere de afișat - bucla le va transmite unei variabile și va executa „corpul buclei”. De îndată ce lista de fișiere din director se termină, ciclul își va finaliza execuția.

Să facem exemplul puțin mai complicat.

Directorul conține o listă de fișiere:

$ ls -1 fișier1 fișier2 fișier3 fișier4 fișier5 buclă.sh nofile1 nofile2 nofile3 nofile4 nofile5

Trebuie să le selectăm dintre ei doar pe cei care nu au cuvântul " nu«:

$ cat loop.sh #!/bin/bash lsl=`ls -1` pentru variabila în $lsl do echo "$variable" | grep -v „nu” terminat $ ./loop.sh fișier1 fișier2 fișier3 fișier4 fișier5 buclă.sh

De asemenea, puteți utiliza expresii condiționate într-o buclă ( expresii condiționale) […] pentru a verifica condițiile și instrucțiunea break pentru a întrerupe bucla dacă condiția este declanșată.

Luați în considerare acest exemplu:

$ cat loop.sh #!/bin/bash lsl=`ls -1` pentru variabila din $lsl do if [ $variable != "loop.sh" ] then echo "$variable" | grep -v "nu" else break fi terminat

Bucla va continua până când este întâlnit fișierul loop.sh. De îndată ce execuția buclei ajunge la acest fișier, bucla va fi întreruptă de comanda break:

$ ./loop.sh fișier1 fișier2 fișier3 fișier4 fișier5

Un alt exemplu este utilizarea operațiilor aritmetice imediat înainte de a executa corpul buclei:

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

Aici setăm trei comenzi de control - count=1, o condiție de control - în timp ce numărul este mai mic de 11 și o comandă de executat - count +1:

bucle WHILE și UNTIL

Un exemplu simplu care demonstrează clar cum funcționează bucla while:

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

Setăm variabila $count la zero și apoi rulăm bucla whi cu condiția „în timp ce $count este mai mic de zece, executam bucla”. În corpul buclei executăm increment postfix+1 la variabila $count și rezultatul este tipărit în stdout.

Rezultatul executiei:

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

De îndată ce valoarea variabilei $count a devenit 10, bucla s-a oprit.

Un bun exemplu de buclă „infinită” care demonstrează cum funcționează 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

Bucla până funcționează în mod similar, dar în direcția opusă:

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

Aici setăm o condiție similară, dar în loc de „în timp ce variabila este mai mică de 10”, specificăm „până când variabila devine mai mare de 10”. Rezultatul executiei:

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

Dacă exemplul de mai sus de „buclă fără sfârșit” este executat folosind până, nu va scoate nimic, spre deosebire de while:

$ cat loop.sh #!/bin/bash count=10 până la [ 1 = 1 ] do ((count++)) echo $count done $ ./loop.sh $

pentru ca" stare"iniţial" adevărat„—corpul buclei nu va fi executat.

La fel ca în bucla for, puteți folosi funcții în while și until. De exemplu, o buclă dintr-un script real care verifică starea serverului Motan(PID este preluat din sistem SLES, poate diferi în alte sisteme), o versiune ușor simplificată:

$ cat loop.sh #!/bin/bash check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(printează $2)"` ) în timp ce check_tomcat_status do if [ -n "$ RUN" ] apoi printf "AVERTISMENT: Tomcat încă rulează cu PID $RUN."

Rezultatul executiei:

else printf "Tomcat s-a oprit, continuă... nn" break fi done

$ ./loop.sh AVERTISMENT: Tomcat încă rulează cu PID 14435 26548. AVERTISMENT: Tomcat încă rulează cu PID 14435 26548. AVERTISMENT: Tomcat încă rulează cu PID 14435 26548. AVERTISMENT: Tomcat încă rulează cu PID 14435 26548. rulează cu PID 14435 26548. AVERTISMENT: Tomcat încă rulează cu PID 14435 26548. AVERTISMENT: Tomcat încă rulează cu PID 14435 26548. AVERTISMENT: Tomcat încă rulează cu PID 14435

Versiune completa:

Check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) în timp ce verificați_tomcat_status; face if [ -n "$RUN" ] then printf "AVERTISMENT: Tomcat încă rulează cu PID $RUN. Oprește-l? " răspunde la "Oprirea Tomcat..." "Se continuă instalarea..." && $CATALINA_HOME/bin/shutdown sh 2&>1 /dev/null || întrerupeți somnul 2 dacă [ -n "$RUN" ] apoi printf "Tomcat încă rulează. Omorâți-l? " răspunde "Killing Tomcat..." "Se continuă instalarea...n" && kill $RUN || break sleep 2 fi else printf "Tomcat oprit, continuă... nn" break fi terminat

Răspuns () ( în timp ce se citește răspunsul; face eco caz $răspuns în |) printf "$1n" return 0 break ;;

|) printf "$2n" returnează 1 pauză ;;

*) printf "Vă rugăm, introduceți Y(da) sau N(nu)!" esac done ) Aici a fost posibil să se folosească atât while, cât și până - dar nu o buclă for, deoarece for ar fi funcționat o dată (a primit PID-ul și s-a încheiat). Buclele sunt un lucru extrem de convenabil atunci când scrieți orice programe sau scripturi, mai degrabă chiar necesare. Ele ne permit să executăm o anumită secțiune de cod de un anumit număr de ori. Desigur, bash are mai multe tipuri de bucle. Vom descrie ciclurile

pentru în, pentru, în timp ce, până:

. Deși pentru în și pentru sunt considerate sintaxe diferite ale aceleiași declarații, în opinia mea, ele diferă unele de altele mai mult decât while from până. Bucla cu contor pentru intrare Ciclu
pentru in
Aceasta este o buclă cu un contor. Blocul de cod situat în corpul buclei se repetă de câte ori există valori conținute în lista operatorului for in, iar la fiecare repetare, variabila contor (aici se numește var, dar bineînțeles). îl poți numi cum vrei) are valoarea următorului element al listei.<список>Dacă cuvântul cheie do este pe aceeași linie cu cuvântul for, atunci după lista de argumente (înainte de do) trebuie să puneți punct și virgulă.<списке>Fiecare dintre elemente
poate conține mai multe argumente. Acest lucru este util atunci când procesați grupuri de parametri. În acest caz, pentru a forța analizarea fiecărui argument din
#!/bin/bash pentru contor în (1..20) face ecou numărare de la 1 la 20, valoarea curentă $counter sleep 1 terminat<списке>, trebuie să utilizați instrucțiunea setată
Puteți utiliza o variabilă ca listă într-o buclă for.<список>Bucla for poate folosi nume de fișiere, care la rândul lor pot conține caractere wildcard. Acest lucru poate fi foarte util atunci când lucrați cu un număr mare de fișiere.
Dacă
nu este specificată în bucla for, atunci variabila $@ este folosită ca ea - o listă de argumente din linia de comandă.

Când creați o listă de argumente, puteți utiliza înlocuirea comenzii într-o buclă for.
Ieșirea buclei poate fi redirecționată de la stdout la un fișier sau în altă parte (puteți afla mai multe despre acest lucru uitându-vă la redirecționarea I/O).<список>
Sintaxă:
<выполняемые команды>
pentru var in

do
făcut
Sintaxă:
Exemplu:
pentru var in

pentru nume în nume1 nume2 nume3 nume4 echo $nume Operator de buclă<приращение счётчиков>valoarea contoarelor noastre variabile trebuie neapărat să se schimbe (nu neapărat în sus) astfel încât la verificarea condiției, mai devreme sau mai târziu să obținem valoarea falsă, altfel bucla nu se va termina niciodată. O opțiune foarte convenabilă și, cel mai important, familiară dacă orice operațiune trebuie repetată de un anumit număr de ori.

Cu o sintaxă similară:
pentru ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
Sintaxă:
<выполняемые команды>
pentru var in

do
pentru ((var=1; var<= LIMIT ; var++))
Sintaxă:
echo $var
pentru var in

bucla while:

Aceasta este o construcție destul de simplă care verifică starea din spatele operatorului în timp ce iar dacă această condiție este adevărată, execută blocul de comenzi situat între cuvintele do și done și apoi trece din nou la verificarea condiției. Dacă verificarea revine false, ciclul se termină și următoarele comenzi încep să fie executate: făcut. Este imperativ să se asigure că<проверка условия>depinde de codul care rulează în buclă, altfel, dacă rezultatul verificării nu se schimbă, veți obține o buclă infinită.
Dispozitivul de intrare standard pentru o buclă while poate fi redirecționat către un fișier folosind comanda de redirecționare< в конце цикла.

Când creați o listă de argumente, puteți utiliza înlocuirea comenzii într-o buclă for.
în timp ce<Проверка условия>
Sintaxă:
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
pentru var in

do
în timp ce [ $var0 -eq 100 ]
Sintaxă:
echo $var
var++
pentru var in

Operator în timp ce poate avea mai multe condiții. Dar numai ultima dintre ele determină posibilitatea continuării ciclului. În acest caz, sintaxa operatorului buclă va fi diferită de cea obișnuită.
Sintaxă(Repet încă o dată că doar ultima condiție afectează execuția buclei) :
în timp ce
<условие1>
<условие2>

<условиеN>
Sintaxă:
<выполняемые команды - тело цикла>
pentru var in

Până la bucla:

Operator până este foarte asemănător cu while, evaluează și condiția, dar execută corpul buclei dacă rezultatul calculului este fals. Poate părea neobișnuit, dar până evaluează starea înainte de prima trecere a buclei, cum ar fi while, și nu după aceasta. Ca și în cazul buclelor for/in, atunci când plasați cuvântul cheie do pe aceeași linie cu declarația buclei, trebuie să introduceți un caracter „;”. înainte de a face.
Ca și în cazul precedent, este important să ne amintim că condiția trebuie să depindă de operațiunile din corpul buclei, altfel scriptul nostru nu se va finaliza niciodată.

Când creați o listă de argumente, puteți utiliza înlocuirea comenzii într-o buclă for.
până<Проверка условия>
Sintaxă:
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
pentru var in

do
până la [ $var0 -gt 100] # Condiția este verificată la începutul iterației.
Sintaxă:
echo $var
var--
pentru var in

Este probabil suficient pentru moment. :)

  • Spate
  • Redirecţiona

Articole noi:

  • Descoperirea rețelei nu se activează în Windows 7/8/2008/2012
  • Eroare: această aplicație nu a reușit să pornească deoarece nu a putut găsi sau încărca pluginul platformei Qt „windows”.
  • Configurarea repornirii automate a proceselor de lucru rphost.exe pe serverul 1C 8.3
  • Cum se reduce dimensiunea jurnalului de tranzacții (.ldf) în MS SQL 2008/20012

    MS SQL, ca orice SGBD industrial decent, împreună cu baza de date, păstrează jurnalele de tranzacții care vă permit să anulați starea...

0 Meeran Bala-Kumaran

Chiar încerc să înțeleg de ce această buclă while nu se termină niciodată, când pornește bucla, variabila mea LOC este setată la Testing/ care este directorul pe care l-am creat pentru a testa acest program are următorul aspect:

Vreau ca bucla să se încheie odată ce toate directoarele au aplicată funcția „număr”.
Iată ce am încercat;

Am verificat funcția de numărare și nu creează o buclă infinită

Am încercat să rulez algoritmul manual

PARSE=1 LOC=$LOC/ count AVAILABLEDIR=$(ls $LOC -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") în timp ce [ $PARSE = "1" ] do if [[ $(AVAILABLEDIR[@]) == "" ]]; apoi PARSE=0 fi DIRBASE=$LOC pentru a în $(AVAILABLEDIR[@]); do LOC="$(DIRBASE)$(a)" LOCLIST="$LOCLIST $LOC" numărare efectuată pentru a în $(LOCLIST[@]); face TMPAVAILABLEDIR=$(ls $a -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") PREPEND=$a if [[ $(TMPAVAILABLEDIR[@]) == "" ] ]; apoi continuați fi pentru a în $(TMPAVAILABLEDIR[@]); face TMPAVAILABLEDIR2="$TMPAVAILABLEDIR2 $(PREPEND[@])$(a)" terminat NEWAVAILABLEDIR="$NEWAVAILABLEDIR $TMPAVAILABLEDIR2" terminat AVAILABLEDIR=$NEWAVAILABLEDIR NEWAVAILABLEDIR="" LOC="" terminat

Chiar mă chinui și orice contribuție ar fi foarte apreciată, am încercat să-mi dau seama în ultimele două ore.

bash buclă infinită

4 raspunsuri

Ar trebui să încercați să rulați scriptul cu argumentul -x sau să îl scrieți pe prima linie:

#!/bin/bash -x

Apoi îți spune tot ce face.

În acest caz, este posibil să observați două erori:

    Nu reîncărcați niciodată TMPAVAILABLEDIR2

    De asemenea, faci ls pe fișiere obișnuite.

Dacă într-adevăr trebuie să evitați recursiunea, încercați acest lucru, complet fără recursivitate:

#!/bin/bash count() (numărarea ecoului „$1” ) todo=(Testing) în timp ce testează $(#todo[@]) != 0 do doit=("$(todo[@])") tot= () pentru dir în „$(doit[@])” face pentru intrarea în „$dir”/* # dacă directorul este gol, aceasta arată o intrare numită „*” do test -e „$entry” || continua # sări peste intrarea „*” a unui număr de director gol „$entry” test -d „$entry” || continua tot+=("$entry") gata gata

Totuși, vă rog să-mi spuneți de ce nu puteți utiliza recursiunea? Este un fel de alergie? Jurământ? Există legi locale împotriva software-ului recursiv acolo unde locuiți?

Ai scris că vrei să faci o „numărătoare” pe toate tăieturile. Consultați opțiunile de căutare:

Găsiți $LOC -tip d | while read dir; do cd $LOC cd $(dir) numărare terminat

sau mai scurt (când contorul de funcții ia directorul ca parametru 1)

Găsiți $LOC -tip d | xargs count

Acum văd că nu doriți să utilizați find sau ls -R (funcție recursiv). Atunci ar trebui să vă creați propria funcție recursivă ca

Funcția parseDir ( ls -d */ $1 | în timp ce se citește dir; nu contează parseDir $1/$dir făcut )

Nu am idee dacă va funcționa, dar este o întrebare interesantă la care nu mă puteam opri să mă gândesc. Noroc

În timp ce este adevărat; do pentru cuvânt în "$(echo *)"; face if [[ -d "$cuvânt" ]] ; apoi d[$((i++))]="$PWD"/"$word" elif [[ -f "$word" ]] ;apoi f[$((j++))]="$PWD"/"$ cuvânt" fi făcut [[ $k -gt $i ]] && cd .. cd "$d[$((k++))]" || pauză făcută



 


Citire:



Tehnologia Thunderbolt: cum funcționează și care sunt avantajele acesteia

Tehnologia Thunderbolt: cum funcționează și care sunt avantajele acesteia

Cred că aproape toți știți că există o astfel de interfață precum Thunderbolt 3 (TB3). Aceasta este cea mai recentă versiune de Thunderbolt. Prima versiune a TB...

Cum să crești TIC și PR Cum să crești singur TIC Yandex

Cum să crești TIC și PR Cum să crești singur TIC Yandex

TIC este un index tematic de citare a site-ului. Abrevierea este familiară multor oameni, este adesea folosită de webmasteri și de internet -...

Versiunea de kernel 3.10. Afișarea intermitentă a nucleului unui dispozitiv Android. Care este nucleul unui dispozitiv mobil?

Versiunea de kernel 3.10.  Afișarea intermitentă a nucleului unui dispozitiv Android.  Care este nucleul unui dispozitiv mobil?

Duminică seara, Linus Torvalds, părintele Linux și dezvoltatorul nucleului sistemului de operare, a anunțat după două luni de muncă...

Recuperare folosind discul de instalare

Recuperare folosind discul de instalare

Buna admin. Întrebarea este aceasta. Windows-ul meu 8 are doi ani și vreau să spun că în tot acest timp l-am folosit activ și am instalat un...

imagine-alimentare RSS