Secțiuni de site
Alegerea editorului:
- Cum să apelați direct un operator Beeline „în direct”: numere de telefon gratuite
- Cititoare PDF esențiale
- Lineage II - Interlude: The Chaotic Throne nu va începe?
- Recuperarea parolei Excel
- Cum să adăugați un nou cadran de ceas pe ceasurile inteligente Android Wear
- Cel mai profitabil plan tarifar Life
- Cum să transferați date de la Samsung la contactele Google Xiaomi Miui
- Filtre de imagine CSS Funcțiile și sintaxa filtrelor CSS
- Toate culorile carcasei Galaxy S8 și care este mai bine să o cumpărați?
- Mikrotik hAP AC - Un router pentru toate ocaziile Înainte de a începe testarea
Publicitate
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 Scripturicomanda de testareComanda 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 economisimacest 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 elifPuteț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ăcutBuclele 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 scripturi3. 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. Iterarea peste valori simplePoate 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
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 complexeLista 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
Inițializarea unei bucle cu o listă obținută din rezultatele comenziiO 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
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âmpMotivul 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:
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" #!/bin/bash file="/etc/passwd" IFS=$"\n" pentru var în $(cat $fișier) do echo " $var" gata
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 directorUna 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 Acesta este ceea ce va scoate scriptul.
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 bucleDacă 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);
}
Pentru ((valoarea inițială a variabilei; condiția pentru încheierea buclei; schimbarea variabilei)) Pentru ((a = 1; a< 10; a++))
#!/bin/bash pentru ((i=1; i<= 10; i++))
do
echo "number is $i"
done
Buclă în stil C buclă whileConstrucț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 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 Rezultatul buclei while Dacă nu modificați variabila $var1, acest lucru va face ca scriptul să ajungă într-o buclă infinită. Bucle imbricatePuteț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
Bucle imbricate Procesarea conținutului fișieruluiCel 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 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 cicluluiPoate 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:
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 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 continua comandaCâ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
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”. Redirecționați ieșirea buclei către fișier Exemplu: Căutați fișiere executabileSă 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 Căutarea fișierelor executabile în foldere din variabila PATH RezultateAstă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); FOR LoopLuaț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 UNTILUn 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 Când creați o listă de argumente, puteți utiliza înlocuirea comenzii într-o buclă for. do 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ă: do 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ă. Când creați o listă de argumente, puteți utiliza înlocuirea comenzii într-o buclă for. do 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ă. <условиеN> 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. Când creați o listă de argumente, puteți utiliza înlocuirea comenzii într-o buclă for. do Este probabil suficient pentru moment. :)
Articole noi:
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”. 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 raspunsuriAr 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ă |
Popular:
Nou
- Cititoare PDF esențiale
- Lineage II - Interlude: The Chaotic Throne nu va începe?
- Recuperarea parolei Excel
- Cum să adăugați un nou cadran de ceas pe ceasurile inteligente Android Wear
- Cel mai profitabil plan tarifar Life
- Cum să transferați date de la Samsung la contactele Google Xiaomi Miui
- Filtre de imagine CSS Funcțiile și sintaxa filtrelor CSS
- Toate culorile carcasei Galaxy S8 și care este mai bine să o cumpărați?
- Mikrotik hAP AC - Un router pentru toate ocaziile Înainte de a începe testarea
- Cum să calculezi cel mai bine reflexul de bas pentru un sistem acustic