Bash infinite loop. Infinite while loop sa BASH script

💖 Gusto mo ba? Ibahagi ang link sa iyong mga kaibigan
Sinusuportahan ng bash shell ang mga loop, na nagbibigay-daan sa iyong umulit sa mga pagkakasunud-sunod ng mga halaga. Narito ang pangunahing istraktura ng naturang mga loop:

Para sa var sa listahan gawin command tapos na
Sa bawat pag-ulit ng loop, ang susunod na halaga mula sa listahan ay isusulat sa var variable. Ang unang pass ng loop ay samakatuwid ay gagamit ng unang halaga mula sa listahan. Sa pangalawa - ang pangalawa, at iba pa - hanggang sa maabot ng loop ang huling elemento.

Pag-ulit sa mga simpleng halaga

Marahil ang pinakasimpleng halimbawa ng isang for loop sa mga script ng bash ay umuulit sa isang listahan ng mga simpleng halaga:

#!/bin/bash para sa var sa unang pangalawa pangatlo pang-apat na panglima do echo Ang $var item tapos na
Ang mga resulta ng script na ito ay ipinapakita sa ibaba. Malinaw mong makikita na ang $var variable ay naglalaman ng mga elemento mula sa listahan nang sunud-sunod. Nangyayari ito hanggang sa maabot ng cycle ang huli sa kanila.


Simple para sa loop

Pakitandaan na ang variable na $var ay nagpapanatili ng halaga nito kapag lumalabas sa loop, maaaring baguhin ang mga nilalaman nito, at sa pangkalahatan, maaari mong gamitin ito tulad ng anumang iba pang variable.

Pag-ulit sa mga kumplikadong halaga

Ang listahang ginamit upang simulan ang for loop ay maaaring maglaman hindi lamang ng mga simpleng string na binubuo ng isang salita, kundi pati na rin ng mga buong parirala na naglalaman ng ilang salita at mga bantas. Halimbawa, maaaring ganito ang hitsura nito:

#!/bin/bash para sa var sa una "ang pangalawa" "ang pangatlo" "Gagawin ko" do echo "Ito ay: $var" tapos na
Ito ang mangyayari pagkatapos dumaan ang loop na ito sa listahan. Tulad ng nakikita mo, ang resulta ay lubos na inaasahan.


Pag-ulit sa mga kumplikadong halaga
TNW-CUS-FMP - promo code para sa 10% na diskwento sa aming mga serbisyo, magagamit para sa pag-activate sa loob ng 7 araw"

Pagsisimula ng isang loop na may isang listahan na nakuha mula sa mga resulta ng command

Ang isa pang paraan upang simulan ang isang para sa loop ay upang ipasa ito ng isang listahan, na resulta ng isang utos. Dito ginagamit ang pagpapalit ng command upang maisagawa ang mga ito at makuha ang mga resulta ng kanilang trabaho.

#!/bin/bash file="myfile" para sa var sa $(cat $file) gawin echo " $var" tapos na
Ang halimbawang ito ay gumagamit ng cat command, na nagbabasa ng mga nilalaman ng isang file. Ang resultang listahan ng mga halaga ay ipinasa sa loop at ipinapakita sa screen. Pakitandaan na ang file na aming ina-access ay naglalaman ng isang listahan ng mga salita na pinaghihiwalay ng mga bagong linya;


Isang loop na umiikot sa mga nilalaman ng isang file

Dito dapat nating isaalang-alang na ang gayong diskarte, kung inaasahan ang pagpoproseso ng data sa bawat linya, ay hindi gagana para sa isang file ng isang mas kumplikadong istraktura, ang mga linya na maaaring maglaman ng ilang mga salita na pinaghihiwalay ng mga puwang. Ang loop ay magpoproseso ng mga indibidwal na salita, hindi mga linya.

Paano kung hindi ito ang kailangan mo?

Mga separator ng field

Ang dahilan para sa tampok sa itaas ay ang espesyal variable ng kapaligiran, na tinatawag na IFS (Internal Field Separator) at nagbibigay-daan sa iyong tukuyin ang mga field separator. Bilang default, isinasaalang-alang ng bash shell ang mga sumusunod na character bilang mga field delimiter:
  • kalawakan
  • Character ng tab
  • Line feed character
Kung nakatagpo ng bash ang alinman sa mga character na ito sa data, ipinapalagay nito na nauuna ito ng susunod na independiyenteng halaga sa listahan.

Upang malutas ang isyu, maaari mong pansamantalang baguhin ang variable ng kapaligiran ng IFS. Narito kung paano ito gawin sa isang script ng bash, sa pag-aakalang kailangan mo lamang ng isang bagong linya bilang isang field separator:

IFS=$"\n"
Kapag naidagdag mo na ang command na ito sa iyong bash script, gagana ito gaya ng inaasahan, hindi papansinin ang mga puwang at tab at ituturing lang ang mga newline na character bilang mga field separator.

#!/bin/bash file="/etc/passwd" IFS=$"\n" para sa var sa $(cat $file) gawin echo " $var" tapos na
Kung ang script na ito ay tatakbo, ito ay maglalabas nang eksakto kung ano ang kinakailangan dito, na nagbibigay, sa bawat pag-ulit ng loop, ng access sa susunod na linya na nakasulat sa file.


Linya sa pamamagitan ng linya na traversal ng isang file sa isang for loop

Ang mga separator ay maaari ding iba pang mga character. Halimbawa, sa itaas ay ipinakita namin ang mga nilalaman ng /etc/passwd file. Ang data ng user sa mga linya ay pinaghihiwalay ng mga tutuldok. Kung kailangan mong iproseso ang mga naturang string sa isang loop, maaaring i-configure ang IFS tulad nito:

Paglalakbay sa mga file na nasa isang direktoryo

Ang isa sa mga pinakakaraniwang gamit ng para sa mga loop sa mga script ng bash ay ang pagtawid sa mga file na matatagpuan sa isang direktoryo at iproseso ang mga file na iyon.

Halimbawa, narito kung paano maglista ng mga file at folder:

#!/bin/bash para sa file sa /home/likegeeks/* gawin kung [ -d "$file" ] pagkatapos ay echo "$file ay isang direktoryo" elif [ -f "$file" ] pagkatapos ay echo "$file ay isang file" tapos na
Kung naunawaan mo ang nakaraang materyal sa seryeng ito ng mga artikulo, dapat mong maunawaan ang istraktura ng if-then construct, pati na rin kung paano makilala ang isang file mula sa isang folder. Kung nahihirapan kang maunawaan ang code sa itaas, basahin muli ang materyal na ito.

Ito ang ilalabas ng script.


Pagpapakita ng mga nilalaman ng isang folder

Pansinin kung paano namin sinisimulan ang loop, katulad ng wildcard na "*" sa dulo ng address ng folder. Ang simbolo na ito ay maaaring isipin bilang isang wildcard na kahulugan: "lahat ng mga file na may anumang mga pangalan." pinapayagan ka nitong ayusin ang awtomatikong pagpapalit ng mga pangalan ng file na tumutugma sa pattern.

Kapag sinusubukan ang isang kundisyon sa isang if statement, isinama namin ang variable na pangalan sa mga quote. Ginagawa ito dahil ang pangalan ng file o folder ay maaaring maglaman ng mga puwang.

C-style para sa mga loop

Kung pamilyar ka sa C programming language, ang syntax para sa paglalarawan ng bash para sa mga loop ay maaaring mukhang kakaiba sa iyo, dahil malinaw na sanay ka sa paglalarawan ng mga loop sa ganitong paraan:

Para sa (i = 0; i< 10; i++) { printf("number is %d\n", i); }
Sa mga script ng bash na maaari mong gamitin para sa mga loop, ang paglalarawan kung saan ay mukhang halos kapareho sa mga C-style na mga loop, kahit na may ilang mga pagkakaiba. Ang cycle diagram na may ganitong diskarte ay ganito ang hitsura:

Para sa ((paunang halaga ng variable; kundisyon para sa pagtatapos ng loop; pagbabago ng variable))
Sa bash maaari itong isulat tulad nito:

Para sa ((a = 1; a< 10; a++))
Narito ang isang gumaganang halimbawa:

#!/bin/bash para sa ((i=1; i<= 10; i++)) do echo "number is $i" done
Ang code na ito ay maglalabas ng isang listahan ng mga numero mula 1 hanggang 10.

Pag-looping sa istilong C

habang umiikot

Ang para sa konstruksyon ay hindi lamang ang paraan upang ayusin ang mga loop sa mga script ng bash. Maaari mo ring gamitin ang while loops dito. Sa ganoong loop, maaari mong tukuyin ang isang command upang suriin ang isang tiyak na kundisyon at isakatuparan ang katawan ng loop hanggang sa ang kundisyong sinusuri ay bumalik sa zero, o isang senyas para sa matagumpay na pagkumpleto ng isang tiyak na operasyon. Kapag nagbalik ang kundisyon ng loop ng hindi zero na halaga, na nangangahulugang isang error, titigil ang loop.

Narito ang isang diagram ng organisasyon ng while loops
habang utos ng condition check
gawin
ibang mga koponan
tapos na

Tingnan natin ang isang halimbawa ng script na may loop na tulad nito:

#!/bin/bash var1=5 habang ang [ $var1 -gt 0 ] echo $var1 var1=$[ $var1 - 1 ] tapos na
Sa pasukan sa loop, sinusuri kung ang variable na $var1 ay mas malaki sa zero. Kung gayon, ang katawan ng loop ay isinasagawa, kung saan ang isa ay ibabawas mula sa halaga ng variable. Nangyayari ito sa bawat pag-ulit, at ini-print namin ang halaga ng variable sa console bago ito mabago. Sa sandaling maabot ng $var1 ang value na 0, hihinto ang loop.

Resulta ng while loop

Kung hindi mo babaguhin ang $var1 variable, magiging sanhi ito ng script na mauwi sa isang walang katapusang loop.

Nested Loops

Maaari mong gamitin ang anumang mga utos sa katawan ng loop, kabilang ang paglulunsad ng iba pang mga loop. Ang ganitong mga konstruksyon ay tinatawag na mga nested loop:

#!/bin/bash para sa ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
Nasa ibaba ang ilalabas ng script na ito. Tulad ng nakikita mo, una ang unang pag-ulit ng panlabas na loop ay naisakatuparan, pagkatapos ay tatlong pag-ulit ng panloob na isa, pagkatapos nito makumpleto ang panlabas na loop ay muling naglaro, pagkatapos ay ang panloob na muli.

Nested Loops

Pagproseso ng Mga Nilalaman ng File

Kadalasan, ang mga nested loop ay ginagamit upang iproseso ang mga file. Kaya, ang panlabas na loop ay umuulit sa mga linya ng file, at ang panloob ay gumagana na sa bawat linya. Narito, halimbawa, kung ano ang hitsura ng pagproseso ng /etc/passwd file:

#!/bin/bash IFS=$"\n" para sa pagpasok sa $(cat /etc/passwd) gawin echo "Mga halaga sa $entry -" IFS=: para sa halaga sa $entry gawin echo " $value" tapos na tapos na
Mayroong dalawang mga loop sa script na ito. Ang una ay dumadaan sa mga linya gamit ang newline na character bilang isang delimiter. Ang panloob ay abala sa pag-parse ng mga string na ang mga field ay pinaghihiwalay ng mga tutuldok.

Pagproseso ng Data ng File

Maaaring gamitin ang diskarteng ito kapag nagpoproseso ng mga CSV file, o anumang katulad na file, sa pamamagitan ng pagsusulat ng delimiter character sa IFS environment variable kung kinakailangan.

Pamamahala ng cycle

Marahil, pagkatapos na ipasok ang loop, kakailanganin mong ihinto ito kapag ang loop variable ay umabot sa isang tiyak na halaga na hindi tumutugma sa unang tinukoy na kondisyon para sa pagtatapos ng loop. Sa ganitong sitwasyon, kakailanganin bang maghintay para sa normal na pagkumpleto ng cycle? Siyempre hindi, at sa mga ganitong kaso ang sumusunod na dalawang utos ay magiging kapaki-pakinabang:
  • break
  • magpatuloy

masira ang utos

Ang utos na ito ay nagpapahintulot sa iyo na matakpan ang pagpapatupad ng isang loop. Maaari itong magamit para sa parehong para sa at habang mga loop:

#!/bin/bash para sa var1 sa 1 2 3 4 5 6 7 8 9 10 gawin kung [ $var1 -eq 5 ] pagkatapos ay masira ang fi echo "Number: $var1" tapos na
Ang ganitong loop, sa ilalim ng normal na mga kondisyon, ay dadaan sa buong listahan ng mga halaga mula sa listahan. Gayunpaman, sa aming kaso, maaantala ang pagpapatupad nito kapag ang $var1 variable ay katumbas ng 5.

Maagang lumabas sa isang for loop

Narito ang parehong bagay, ngunit para sa while loop:

#!/bin/bash var1=1 habang [ $var1 -lt 10 ] gawin kung [ $var1 -eq 5 ] pagkatapos ay masira ang fi echo "Iteration: $var1" var1=$(($var1 + 1)) tapos na
Ang break command, na isinagawa kapag ang $var1 ay umabot sa 5, ay sinira ang loop. Ipapakita ng console ang parehong bagay tulad ng sa nakaraang halimbawa.

patuloy na utos

Kapag ang utos na ito ay nakatagpo sa katawan ng loop, ang kasalukuyang pag-ulit ay nagtatapos nang maaga at ang susunod ay magsisimula, nang hindi lumalabas sa loop. Tingnan natin ang continue command sa isang for loop:

#!/bin/bash para sa ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
Kapag ang kundisyon sa loob ng loop ay nasiyahan, iyon ay, kapag ang $var1 ay mas malaki sa 5 at mas mababa sa 10, ang shell ay nagpapatupad ng continue command. Nagreresulta ito sa paglaktaw sa natitirang mga utos sa katawan ng loop at lumipat sa susunod na pag-ulit.

Ang continue command sa isang for loop

Pagproseso ng Output na Tumatakbo sa isang Loop

Ang output ng data mula sa isang loop ay maaaring iproseso sa pamamagitan ng alinman sa pag-redirect ng output o pagpasa nito sa isang pipeline. Ginagawa ito sa pamamagitan ng pagdaragdag ng mga utos sa pagpoproseso ng output pagkatapos ng tapos na pahayag.

Halimbawa, sa halip na ipakita sa screen kung ano ang output sa isang loop, maaari mong isulat ang lahat ng ito sa isang file o ipasa ito sa ibang lugar:

#!/bin/bash para sa ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt echo "tapos na."
Gagawin ng shell ang file na myfile.txt at ire-redirect ang output ng for statement sa file na iyon. Buksan natin ang file at tiyaking naglalaman ito ng eksaktong inaasahan natin.

I-redirect ang output ng loop sa file

Halimbawa: Maghanap ng mga executable na file

Gamitin natin ang natalakay na natin at magsulat ng kapaki-pakinabang. Halimbawa, kung kailangan mong malaman kung aling mga executable na file ang available sa system, maaari mong i-scan ang lahat ng mga folder na naitala sa PATH environment variable. Mayroon na kaming buong arsenal ng mga tool na kailangan namin para dito, kailangan lang naming pagsamahin ang lahat:

#!/bin/bash IFS=: para sa folder sa $PATH gawin echo "$folder:" para sa file sa $folder/* gawin kung [ -x $file ] pagkatapos ay echo " $file" tapos na
Ang script na ito, maliit at simple, ay nagbigay-daan sa amin na makakuha ng isang listahan ng mga executable na file na nakaimbak sa mga folder mula sa PATH.

Naghahanap ng mga executable na file sa mga folder mula sa PATH variable

Mga resulta

Ngayon ay pinag-usapan natin ang tungkol sa for and while loops sa mga bash script, kung paano patakbuhin ang mga ito, kung paano pamahalaan ang mga ito. Ngayon alam mo na kung paano iproseso ang mga string na may iba't ibang mga delimiter sa mga loop, alam mo kung paano i-redirect ang output ng data sa mga loop sa mga file, kung paano tingnan at pag-aralan ang mga nilalaman ng mga direktoryo.

Kung ipagpalagay namin na ikaw ay isang developer ng mga script ng bash na nakakaalam lamang tungkol sa mga ito kung ano ang nakasaad sa unang bahagi ng seryeng ito ng mga artikulo, at sa pangalawang ito, maaari ka nang magsulat ng isang bagay na kapaki-pakinabang. Sa unahan ay ang ikatlong bahagi, pagkatapos maunawaan kung saan matututunan mo kung paano ipasa ang mga parameter at ang command line ay lumipat sa mga script ng bash, at kung ano ang gagawin sa lahat ng ito.

0 Meeran Bala-Kumaran

Sinusubukan ko talagang unawain kung bakit hindi natatapos ang while loop na ito, kapag nagsimula ang loop ang aking LOC variable ay nakatakda sa Testing/ na siyang direktoryo na ginawa ko upang subukan ang program na ito ay may sumusunod na layout:

Gusto kong matapos ang loop sa sandaling ang lahat ng Direktoryo ay nagkaroon ng "count" function na inilapat.
Narito kung ano ang sinubukan ko;

Sinuri ko ang function ng count at hindi ito lumikha ng isang walang katapusang loop

Sinubukan kong patakbuhin nang manu-mano ang algorithm

PARSE=1 LOC=$LOC/ count AVAILABLEDIR=$(ls $LOC -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") habang [ $PARSE = "1" ] gawin kung [[ $(AVAILABLEDIR[@]) == "" ]]; pagkatapos ay PARSE=0 fi DIRBASE=$LOC para sa isang sa $(AVAILABLEDIR[@]); gawin ang bilang ng LOC="$(DIRBASE)$(a)" LOCLIST="$LOCLIST $LOC" para sa isang sa $(LOCLIST[@]); gawin TMPAVAILABLEDIR=$(ls $a -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") PREPEND=$a kung [[ $(TMPAVAILABLEDIR[@]) == "" ] ]; pagkatapos ay ipagpatuloy ang fi para sa isang sa $(TMPAVAILABLEDIR[@]); gawin TMPAVAILABLEDIR2="$TMPAVAILABLEDIR2 $(PREPEND[@])$(a)" tapos NEWAVAILABLEDIR="$NEWAVAILABLEDIR $TMPAVAILABLEDIR2" tapos AVAILABLEDIR=$NEWAVAILABLEDIR NEWAVAILABLEDIR="" LOC="" tapos na

Ako ay talagang struggling at anumang input ay lubos na pinahahalagahan, sinubukan kong malaman ito sa huling dalawang oras.

bash infinite-loop

4 na sagot

Dapat mong subukang patakbuhin ang script gamit ang -x na argumento o isulat ito sa unang linya:

#!/bin/bash -x

Tapos sasabihin niya lahat ng ginagawa niya.

Sa kasong ito, maaari mong mapansin ang dalawang error:

    Hindi mo kailanman nire-reload ang TMPAVAILABLEDIR2

    Ginagawa mo rin ang ls sa mga regular na file.

Kung talagang dapat mong iwasan ang recursion, subukan ito, ganap na walang recursion:

#!/bin/bash count() ( echo counting "$1") todo=(Pagsubok) habang pagsubok $(#todo[@]) != 0 do doit=("$(todo[@])") todo= () para sa dir sa "$(doit[@])" do para sa entry sa "$dir"/* # kung walang laman ang dir, nagpapakita ito ng entry na may pangalang "*" do test -e "$entry" || magpatuloy # laktawan ang entry na "*" ng isang walang laman na dir count na "$entry" na pagsubok -d "$entry" || continue todo+=("$entry") tapos tapos tapos na

Gayunpaman, mangyaring sabihin sa akin kung bakit hindi mo magagamit ang recursion? Ito ba ay isang uri ng allergy? Panata? Mayroon bang anumang lokal na batas laban sa recursive software kung saan ka nakatira?

Isinulat mo na gusto mong magsagawa ng "bilang" sa lahat ng mga pagbawas. Tingnan ang mga opsyon sa paghahanap:

Hanapin ang $LOC -type d | habang nagbabasa ng dir; gawin ang cd $LOC cd $(dir) count tapos na

o mas maikli (kapag kinuha ng iyong function counter ang direktoryo bilang parameter 1)

Hanapin ang $LOC -type d | bilang ng xargs

Ngayon nakita ko na hindi mo gustong gumamit ng find o ls -R (recursive function). Pagkatapos ay dapat kang gumawa ng iyong sariling recursive function tulad ng

Function parseDir ( ls -d */ $1 | habang binabasa ang dir; bilangin ang parseDir $1/$dir tapos na )

Wala akong ideya kung gagana ito, ngunit ito ay isang kawili-wiling tanong na hindi ko mapigilang isipin. Good luck

Habang totoo; gawin para sa salita sa "$(echo *)" ; gawin kung [[ -d "$word" ]] ; pagkatapos ay d[$((i++))]="$PWD"/"$salita" elif [[ -f "$salita" ]] ;pagkatapos f[$((j++))]="$PWD"/"$ word" fi tapos [[ $k -gt $i ]] && cd .. cd "$d[$((k++))]" || tapos na ang break

Isang maikling paglalarawan ng pagkakaiba sa mga uri ng loop:

para sa - gagawa ng isang aksyon hangga't may mga bagay na isasagawa (halimbawa, pagbabasa ng stream mula sa stdin, isang file o isang function);
habang - nagsasagawa ng aksyon hanggang kundisyon ay totoo;
hanggang - ay ipapatupad hangga't kundisyon ay hindi magiging totoo, i.e. sa ngayon ito ay hindi totoo.

PARA sa Loop

Isaalang-alang ang bersyong ito ng script na may loop:

$ cat loop.sh #!/bin/bash para sa variable sa `ls -1` gawin echo "$variable" tapos na

Ang syntax ay napaka-simple at malinaw na ipinapakita sa halimbawa:

para sa (simulan ang loop) variable (magdeklara ng variable kung saan kami magsasagawa ng mga aksyon) sa (magpadala ng daloy sa loop) `ls -1` (utos na isasagawa at ipapasa sa $variable variable). Ang gawin at tapos na ay ang "katawan" ng loop, kung saan isasagawa ang mga pangunahing aksyon sa natanggap na data, at ang echo "$variable" ay ang aktwal na pagkilos na isinagawa ng loop.

Ngayon ay baguhin natin nang kaunti ang halimbawa, at sa halip na tahasang tukuyin ang utos, gagamitin natin ang pangalawang variable:

$ cat loop.sh #!/bin/bash ls=`ls -1` para sa variable sa $ls do echo "$variable" tapos

Ngayon ang ls -1 na utos ay ipinasa sa isang hiwalay na variable, na nagbibigay-daan sa iyo upang gumana sa loop nang mas nababaluktot. Sa halip na isang variable sa isang loop, maaari ka ring gumamit ng isang function:

$ cat loop.sh #!/bin/bash lsl () ( ls -1 ) para sa variable sa `lsl` do echo "$variable" tapos na

Ang pangunahing kondisyon ng para sa loop ay na ito ay isasagawa hangga't ang utos na ipinasa dito ay naglalaman ng mga bagay para sa aksyon. Batay sa halimbawa sa itaas - hangga't may mga file na ipapakita ang ls -1 - ipapasa sila ng loop sa isang variable at isasagawa ang "loop body". Sa sandaling matapos ang listahan ng mga file sa direktoryo, makukumpleto ng cycle ang pagpapatupad nito.

Gawin nating mas kumplikado ang halimbawa.

Ang direktoryo ay naglalaman ng isang listahan ng mga file:

$ ls -1 file1 file2 file3 file4 file5 loop.sh nofile1 nofile2 nofile3 nofile4 nofile5

Kailangan nating pumili mula sa kanila lamang ang mga walang salitang " hindi«:

$ cat loop.sh #!/bin/bash lsl=`ls -1` para sa variable sa $lsl do echo "$variable" | grep -v "hindi" tapos na $ ./loop.sh file1 file2 file3 file4 file5 loop.sh

Maaari ka ring gumamit ng mga conditional na expression sa isang loop ( kondisyonal na pagpapahayag) […] upang suriin ang mga kundisyon at ang pahayag ng break upang matakpan ang loop kung ang kundisyon ay na-trigger.

Isaalang-alang ang halimbawang ito:

$ cat loop.sh #!/bin/bash lsl=`ls -1` para sa variable sa $lsl gawin kung [ $variable != "loop.sh" ] pagkatapos ay echo ang "$variable" | grep -v "no" else break fi tapos

Magpapatuloy ang loop hanggang sa makita ang file loop.sh. Sa sandaling maabot ng execution ng loop ang file na ito, ang loop ay maaantala ng break command:

$ ./loop.sh file1 file2 file3 file4 file5

Ang isa pang halimbawa ay ang paggamit ng mga pagpapatakbo ng aritmetika kaagad bago isagawa ang katawan ng loop:

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

Dito nagtakda kami ng tatlong control command - count=1, isang controlling condition - habang ang bilang ay mas mababa sa 11, at isang command na ipapatupad - count +1:

HABANG at HANGGANG mga loop

Isang simpleng halimbawa na malinaw na nagpapakita kung paano gumagana ang while loop:

$ cat loop.sh #!/bin/bash count=0 habang [ $count -lt 10 ] gawin ((count++)) echo $count tapos

Itinakda namin ang $count variable sa zero, at pagkatapos ay patakbuhin ang whi le loop na may kundisyon na "habang ang $count ay mas mababa sa sampu, isagawa ang loop." Sa katawan ng loop isagawa namin pagtaas ng postfix+1 sa $count variable at ang resulta ay naka-print sa stdout.

Resulta ng pagpapatupad:

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

Sa sandaling ang halaga ng $count variable ay naging 10, huminto ang loop.

Isang magandang halimbawa ng isang "walang katapusan" na loop na nagpapakita kung paano gumagana:

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

Ang hanggang loop ay gumagana nang katulad, ngunit sa kabaligtaran ng direksyon:

$ cat loop.sh #!/bin/bash count=0 hanggang [ $count -gt 10 ] gawin ((count++)) echo $count tapos

Dito nagtakda kami ng katulad na kundisyon, ngunit sa halip na "habang ang variable ay mas mababa sa 10," tinukoy namin "hanggang ang variable ay maging mas malaki sa 10." Resulta ng pagpapatupad:

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

Kung ang halimbawa sa itaas ng isang "walang katapusang loop" ay isinasagawa gamit ang hanggang, hindi ito maglalabas ng anuman, hindi tulad ng habang:

$ cat loop.sh #!/bin/bash count=10 hanggang [ 1 = 1 ] gawin ((count++)) echo $count tapos $ ./loop.sh $

kasi" kundisyon» orihinal « totoo"—ang katawan ng loop ay hindi isasagawa.

Tulad ng para sa loop, maaari mong gamitin ang mga function sa habang at hanggang. Halimbawa, isang loop mula sa isang totoong buhay na script na sumusuri sa status ng server Tomcat(Ang PID ay kinuha mula sa system SLES, ay maaaring mag-iba sa ibang mga system), isang bahagyang pinasimple na bersyon:

$ cat loop.sh #!/bin/bash check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) habang check_tomcat_status gawin kung [ -n "$ RUN" ] then printf "WARNING: Tomcat still running with PID $RUN."

Resulta ng pagpapatupad:

else printf "Tumigil ang Tomcat, nagpapatuloy...nn" tapos na ang break fi

$ ./loop.sh WARNING: Tomcat still running with PID 14435 26548.WARNING: Tomcat still running with PID 14435 26548.WARNING: Tomcat still running with PID 14435 26548.WARNING: Tomcat still running with PID 14435 still WARNING: Tomcat still running with PID 14435 WARNING tumatakbo gamit ang PID 14435 26548.WARNING: Tumatakbo pa rin ang Tomcat sa PID 14435 26548.WARNING: Tumatakbo pa rin ang Tomcat sa PID 14435 26548.WARNING: Tumatakbo pa rin ang Tomcat sa PID 14435

Buong bersyon:

Check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) habang check_tomcat_status; gawin kung [ -n "$RUN" ] pagkatapos ay printf "BABALA: Tumatakbo pa rin ang Tomcat sa PID $RUN. Itigil mo ito? " sagot "Stopping Tomcat..." "Proceeding installation..." && $CATALINA_HOME/bin/shutdown . sh 2&>1 /dev/null || break sleep 2 kung [ -n "$RUN" ] then printf "Tumatakbo pa rin ang Tomcat. Patayin ito? " sagot "Killing Tomcat..." "Proceeding installation...n" && kill $RUN || break sleep 2 fi else printf "Tumigil ang Tomcat, nagpapatuloy...nn" tapos na ang break fi

Ang pag-andar ng sagot ay inilarawan sa artikulo, ngunit narito ang isang bahagyang pinabuting bersyon ay ginagamit:

Sagot () ( while read response; do echo case $response in |) printf "$1n" return 0 break ;;


|) printf "$2n" ibalik ang 1 break ;;
*) printf "Pakilagay, ipasok ang Y(oo) o N(hindi)!" esac tapos na )
Dito posible na gamitin ang parehong habang at hanggang - ngunit hindi para sa loop, dahil para sana ay gumana nang isang beses (natanggap ang PID at natapos).
May-akda: Paul Cobbaut

Petsa ng pag-publish: Oktubre 16, 2014

Pagsasalin: A. Panin

Petsa ng pagsasalin: Disyembre 21, 2014

Kabanata 22. Mga Loop sa Mga Iskrip

Kung mas komportable kang magtrabaho kasama ang mga string na true at false, maaari mong gamitin ang test command tulad ng ipinapakita sa ibaba.

$ test 56 -gt 55 && echo true || echo false true $ test 6 -gt 55 && echo true || echo false false

Ang test command ay maaari ding palitan ng mga square bracket, kaya ang mga command sa halimbawa sa ibaba ay eksaktong kapareho ng mga command sa halimbawa sa itaas.< $bar ] Будет ли строка abc расположена выше значения переменной $bar в списке после сортировки? [ -f foo ] Является ли foo обычным файлом? [ -r bar ] Является ли bar читаемым файлом? [ foo -nt bar ] Новее ли файл foo файла bar ? [ -o nounset ] Активирован ли параметр командной оболочки nounset ?

$ [ 56 -gt 55 ] && echo true || echo false true $ [ 6 -gt 55 ] && echo true || echo false false

Nasa ibaba ang mga halimbawa ng pagpapatupad ng ilang pagsusuri. Tingnan ang man test page para sa mga karagdagang opsyon para sa pagpapatupad ng iba't ibang pagsubok.

[ -d foo ] Umiiral ba ang directory foo? [ -e bar ] Umiiral ba ang bar file? [ "/etc" = $PWD ] Katumbas ba ang /etc sa halaga ng $PWD ? [ $1 != "secret" ] Iba ba ang value ng unang script parameter sa secret string? [ 55 -lt $bar ] Mas mababa ba ang halaga ng integer na 55 kaysa sa halaga ng $bar ? [ $foo -ge 1000 ] Ang halaga ba ng $foo ay mas malaki kaysa o katumbas ng integer value na 1000 ? ["abc"

Ang mga operator ng pagsubok ay maaaring isama sa mga operator na naaayon sa mga lohikal na operator na "AT" at "O".

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 totoo

Maaari kang maglagay ng bagong if statement sa loob ng else block sa pamamagitan ng paggamit ng elif statement. Nasa ibaba ang isang simpleng halimbawa ng naturang entry.

#!/bin/bash count=42 kung [ $count -eq 42 ] pagkatapos ay echo ang "42 ay isang wastong halaga." elif [ $count -gt 42 ] pagkatapos ay i-echo ang "Masyadong marami." else echo "Hindi sapat." fi

para sa loop

Ang halimbawa sa ibaba ay nagpapakita ng syntax ng isang classic para sa loop sa bash shell.

para sa i sa 1 2 4 gawin echo $i tapos na

Isang halimbawa ng paggamit ng for loop na pinagsama sa isang inline na shell call.

#!/bin/ksh para sa counter sa `seq 1 20` gawin ang echo counting mula 1 hanggang 20, kasalukuyang halaga $counter sleep 1 tapos na

Ang isang script na ganap na katulad ng ipinakita sa itaas ay maaaring malikha nang hindi gumagamit ng built-in na shell sa pamamagitan ng paggamit ng bash shell na deklarasyon para sa isang hanay ng mga halaga (mula sa halaga..sa halaga).

#!/bin/bash para sa counter sa (1..20) gawin ang echo counting mula 1 hanggang 20, kasalukuyang halaga $counter sleep 1 tapos na

Ito para sa loop ay gumagamit ng mekanismo para sa paghahanap ng mga file ayon sa pattern (ipinatupad bilang bahagi ng mekanismo ng pagpapalawak ng command). Kung ang pagtuturo sa itaas ay direktang inilagay sa command line, ito ay gagana nang katulad.

kahlan@solexp11$ ls count.ksh go.ksh kahlan@solexp11$ para sa file sa *.ksh ; gawin cp $file $file.backup ; tapos kahlan@solexp11$ ls count.ksh count.ksh.backup go.ksh go.ksh.backup

habang umiikot

Nasa ibaba ang isang simpleng halimbawa ng paggamit ng while loop.

i=100; habang [ $i -ge 0 ] ; gawin ang echo Countdown mula 100 hanggang 0, kasalukuyang halaga $i;

hayaan ko--; tapos na

6. Gamitin ang if statement sa ginawang script para gumana ito ng tama kung walang mga file na may extension na .txt sa kasalukuyang direktoryo.

Ang tamang pamamaraan para sa pagkumpleto ng isang praktikal na gawain: mga pagsusuri at mga loop sa mga script

1. Bumuo ng script na gagamit ng for loop para mabilang mula 3 hanggang 7.

#!/bin/bash para sa i sa 3 4 5 6 7 echo Nagbibilang mula 3 hanggang 7, kasalukuyang halaga $i tapos na

2. Bumuo ng script na gagamit ng for loop upang mabilang mula 1 hanggang 17000.

Ang mga loop ay isang napaka-maginhawang bagay kapag nagsusulat ng anumang mga programa o script, sa halip ay kinakailangan. Pinapayagan nila kaming magsagawa ng isang partikular na seksyon ng code sa isang tiyak na bilang ng beses. Naturally, ang bash ay may ilang uri ng mga loop. Ilalarawan namin ang mga cycle para sa, para sa, habang, hanggang. Bagaman ang para sa at para sa ay itinuturing na magkakaibang mga syntax ng parehong pahayag, sa aking palagay ay naiiba sila sa isa't isa nang higit sa habang mula hanggang.

I-loop na may counter para sa in:

Ikot para sa Ito ay isang loop na may counter. Ang bloke ng code na matatagpuan sa katawan ng loop ay paulit-ulit nang maraming beses hangga't mayroong mga halaga na nilalaman sa listahan ng para sa operator, at sa bawat pag-uulit, ang counter variable (dito ito ay tinatawag na var, ngunit siyempre maaari mo itong tawaging kahit anong gusto mo) ay may halaga ng susunod na elemento ng listahan.
Kung ang keyword na do ay nasa parehong linya ng salita para sa, pagkatapos pagkatapos ng listahan ng mga argumento (bago gawin) kailangan mong maglagay ng semicolon.
Ang bawat isa sa mga elemento<список>maaaring maglaman ng ilang mga argumento. Ito ay kapaki-pakinabang kapag nagpoproseso ng mga pangkat ng mga parameter. Sa kasong ito, upang pilitin ang pag-parse ng bawat isa sa mga argumento<списке>, dapat mong gamitin ang nakatakdang pagtuturo
Maaari kang gumamit ng variable bilang isang listahan sa isang for loop.
SA<списке>Ang for loop ay maaaring gumamit ng mga pangalan ng file, na maaaring maglaman ng mga wildcard na character. Ito ay maaaring maging lubhang kapaki-pakinabang kapag nagtatrabaho sa isang malaking bilang ng mga file.
Kung<список>ay hindi tinukoy sa para sa loop, pagkatapos ay ang $@ variable ay ginagamit bilang ito - isang listahan ng mga argumento ng command line.
Kapag gumagawa ng isang listahan ng mga argumento, maaari mong gamitin ang pagpapalit ng command sa isang for loop.
Ang output ng loop ay maaaring i-redirect mula sa stdout sa isang file o sa ibang lugar (maaari kang matuto nang higit pa tungkol dito sa pamamagitan ng pagtingin sa I/O redirection).

Syntax:
para sa var in<список>
gawin
<выполняемые команды>
tapos na

Halimbawa:
para sa mga pangalan sa name1 name2 name3 name4
gawin
echo $names
tapos na

Operator ng loop para sa ay may isa pang paraan ng pagsulat - halos kapareho sa syntax ng para sa operator sa wikang C Sa kasong ito, kapag sinisimulan ang mga counter, ang mga paunang halaga ng mga variable o isang variable ay nakatakda at pagkatapos ng bawat pass ng loop ang kundisyon. ay naka-check, kung ang tseke ay bumalik na totoo, pagkatapos ay ang susunod na pass ng loop ay magsisimula. Sa block<приращение счётчиков>ang halaga ng aming mga variable na counter ay dapat na kinakailangang magbago (hindi kinakailangang pataas) upang kapag sinusuri ang kundisyon, maaga o huli makuha namin ang halaga na mali, kung hindi, ang loop ay hindi magtatapos. Isang napaka-maginhawa at pinakamahalagang pamilyar na opsyon kung ang anumang operasyon ay kailangang ulitin sa isang tiyak na bilang ng beses.

Na may katulad na syntax:
para sa ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
gawin
<выполняемые команды>
tapos na

Halimbawa:
para sa ((var=1; var<= LIMIT ; var++))
gawin
echo $var
tapos na

habang loop:

Ito ay isang medyo simpleng konstruksyon na sumusuri sa kondisyon sa likod ng operator habang at kung totoo ang kundisyong ito, ipapatupad nito ang bloke ng mga utos na matatagpuan sa pagitan ng mga salitang gawin at tapos na at pagkatapos ay muling magpapatuloy sa pagsuri sa kundisyon. Kung ang tseke ay nagbabalik ng false, ang cycle ay magtatapos at ang mga sumusunod na command ay magsisimulang isagawa: tapos na. Ito ay kinakailangan upang matiyak na<проверка условия>depende sa code na tumatakbo sa loop kung hindi man, kung ang resulta ng tseke ay hindi nagbabago, makakakuha ka ng isang walang katapusang loop.
Ang karaniwang input device para sa isang while loop ay maaaring i-redirect sa isang file gamit ang redirection command< в конце цикла.

Syntax:
habang<Проверка условия>
gawin
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
tapos na

Halimbawa:
habang [ $var0 -eq 100 ]
gawin
echo $var
var++
tapos na

Operator habang maaaring magkaroon ng ilang kundisyon. Ngunit ang huli lamang sa kanila ang tumutukoy sa posibilidad na ipagpatuloy ang pag-ikot. Sa kasong ito, ang syntax ng loop operator ay magiging iba sa karaniwan.
Syntax(Ulitin ko muli na ang huling kundisyon lamang ang nakakaapekto sa pagpapatupad ng loop) :
habang
<условие1>
<условие2>

<условиеN>
gawin
<выполняемые команды - тело цикла>
tapos na

Hanggang sa loop:

Operator hanggang sa ay halos kapareho sa habang, sinusuri din nito ang kundisyon, ngunit isinasagawa ang katawan ng loop kung mali ang resulta ng pagkalkula. Maaaring mukhang hindi karaniwan, ngunit hanggang sa masuri ang kundisyon bago ang unang pass ng loop, tulad ng habang, at hindi pagkatapos nito. Tulad ng para sa/sa mga loop, kapag inilalagay ang do keyword sa parehong linya ng deklarasyon ng loop, dapat kang magpasok ng isang ";" bago gawin.
Tulad ng sa nakaraang kaso, mahalagang tandaan na ang kundisyon ay dapat nakadepende sa mga pagpapatakbo sa loop body, kung hindi, ang aming script ay hinding-hindi makukumpleto.

Syntax:
hanggang sa<Проверка условия>
gawin
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
tapos na

Halimbawa:
hanggang [ $var0 -gt 100] # Sinusuri ang kundisyon sa simula ng pag-ulit.
gawin
echo $var
var--
tapos na

Sapat na siguro sa ngayon. :)

  • Bumalik
  • Pasulong

Mga bagong artikulo:

  • Hindi naka-on ang pagtuklas ng network sa Windows 7/8/2008/2012
  • Error: Nabigong magsimula ang application na ito dahil hindi nito mahanap o mai-load ang Qt platform plugin na "windows".
  • Pag-configure ng awtomatikong pag-restart ng mga proseso ng manggagawa ng rphost.exe sa 1C 8.3 server
  • Paano bawasan ang laki ng log ng transaksyon (.ldf) sa MS SQL 2008/20012

    Ang MS SQL, tulad ng anumang disenteng pang-industriya na DBMS, kasama ang database, ay nagpapanatili ng mga log ng transaksyon na nagpapahintulot sa iyo na ibalik ang estado...

Sabihin sa mga kaibigan