BASH скрипт дэх Infinite while давталт. BASH: for, while, то гогцоонуудын тайлбар ба хэрэглээний жишээ Жишээ: гүйцэтгэх боломжтой файлуудыг хайж байна.


Зохиогч: Пол Коббо
Нийтэлсэн огноо: 2014 оны 10-р сарын 16
Орчуулга: А.Панин
Орчуулсан огноо: 2014 оны 12-р сарын 21

Бүлэг 22. Скрипт дэх гогцоо

туршилтын тушаал

Туршилтын команд нь илэрхийлэл үнэн эсвэл худал эсэхийг тодорхойлох боломжийг олгодог. 10 бүхэл тоо 55-аас их эсэхийг шалгаж эхэлцгээе. $ test 10 -gt 55 ; цуурай $? 1 доллар

Хэрэв илэрхийлэл худал бол тест команд 1-ийг буцаана. Дараах жишээнээс харахад хэрэв илэрхийлэл үнэн бол туршилтын команд 0-ийг буцаана. $ тест 56 -gt 55 ; цуурай $? $0

Хэрэв та үнэн ба худал мөртэй ажиллахад илүү таатай байвал доор үзүүлсэн шиг test командыг ашиглаж болно. $ тест 56 -gt 55 && цуурай үнэн || цуурай худал үнэн $ тест 6 -gt 55 && цуурай үнэн || худал хуурмаг цуурай

Туршилтын командыг мөн дөрвөлжин хаалтаар сольж болох тул доорх жишээн дээрх командууд нь дээрх жишээний командуудтай яг ижил байна. $ [ 56 -gt 55 ] && үнэн цуурай || цуурай худал үнэн $ [ 6 -gt 55 ] && үнэн цуурай || худал хуурмаг цуурай

Зарим шалгалтын хэрэгжилтийн жишээг доор харуулав. Тоймыг харахын тулд man test хуудаснаас үзнэ үү нэмэлт функцуудтөрөл бүрийн шалгалтын хэрэгжилт. [ -d foo ] foo лавлах байдаг уу? [ -e bar ] Бар файл байгаа юу? [ "/etc" = $PWD ] /etc нь $PWD-ийн утгатай тэнцэх үү? [ $1 != "secret" ] Эхний скриптийн параметрийн утга нууц мөрөөс өөр байна уу? [ 55 -lt $bar ] Бүхэл тоо 55 нь $bar-ын утгаас бага байна уу? [ $foo -ge 1000 ] $foo-ийн утга нь 1000 бүхэл тооноос их эсвэл тэнцүү байна уу? ["abc"< $bar ] Будет ли строка abc расположена выше значения переменной $bar в списке после сортировки? [ -f foo ] Является ли foo обычным файлом? [ -r bar ] Является ли bar унших боломжтой файл? [ foo -nt bar ] Foo баарнаас шинэ үү? [ -o nounset ] Nounset shell сонголтыг идэвхжүүлсэн үү?

Шалгах операторуудыг холбогдох операторуудтай нэгтгэж болно логик үйлдлүүд"AND" ба "OR". paul@RHEL4b:~$ [ 66 -gt 55 -a 66 -lt 500 ] && цуурай үнэн || echo false true paul@RHEL4b:~$ [ 66 -gt 55 -a 660 -lt 500 ] && цуурай үнэн || echo false false paul@RHEL4b:~$ [ 66 -gt 55 -o 660 -lt 500 ] && echo true || цуурай худал үнэн

Хэрэв үгүй ​​бол болзолт үсрэлт

if then else бүтэц нь кодын сонголтыг сонгох зорилготой. Хэрэв тодорхой нөхцөл үнэн бол зарим кодыг гүйцэтгэнэ, үгүй ​​бол өөр кодыг гүйцэтгэнэ. Доорх жишээ нь файл байгаа эсэхийг шалгасны дараа тухайн файл байгаа гэсэн таамаглал батлагдвал харгалзах мессеж гарч ирнэ. #!/bin/bash хэрэв [ -f isit.txt ] бол isit.txt файл байгаа гэдгийг цуурай! өөрөөр isit.txt цуурай файл олдсонгүй! fi

Бид хэмнэх тохиолдолд энэ код"сонголт" нэртэй файл дахь скрипт, үүнийг ижил аргаар гүйцэтгэж болно. $ ./choice isit.txt файл олдсонгүй! $ touch isit.txt $ ./сонголт isit.txt файл байна! доллар

Нөхцөлт үсрэлт бол elif

Та нийтэлж болно шинэ оператор elif операторыг ашиглан else блок дотор байвал нөхцөлт үсрэлт. Ийм оруулгын энгийн жишээг доор харуулав. #!/bin/bash count=42 бол [ $count -eq 42 ] бол "42 бол хүчинтэй утга" гэсэн цуурай. elif [ $count -gt 42 ] дараа нь "Хэт олон" гэж цуурайтна. Өөрөөр хэлбэл "Хангалтгүй" гэсэн цуурай. fi

for гогцоо

Доорх жишээнд bash shell дэх сонгодог for давталтын синтаксийг харуулав. for i in 1 2 4 do echo $i done

Inline бүрхүүлийн дуудлагатай хослуулсан for давталтыг ашиглах жишээ. #!/bin/ksh `seq 1 20` дахь тоолуурын хувьд 1-ээс 20 хүртэл цуурайгаар тоолох, одоогийн утга $counter sleep 1 дууссан

Дээр үзүүлсэнтэй бүрэн төстэй скриптийг олон тооны утгын (утга.. утга хүртэл) bash бүрхүүлийн мэдэгдлийг ашиглан суулгагдсан тушаалын бүрхүүл ашиглахгүйгээр үүсгэж болно. (1..20) дахь тоолуурын хувьд #!/bin/bash 1-ээс 20 хүртэл цуурай тоолох, одоогийн утга $counter унтлага 1 дууссан

Энэ for loop нь файлуудыг загвараар хайх механизмыг ашигладаг (командын өргөтгөлийн механизмын нэг хэсэг болгон хэрэгжүүлсэн). Дээрх зааврыг шууд байрлуулсан бол тушаалын мөр, энэ нь адилхан ажиллах болно. *.ksh доторх файлын хувьд kahlan@solexp11$ ls count.ksh go.ksh kahlan@solexp11$; cp $file $file.backup хийх; хийсэн kahlan@solexp11$ ls count.ksh count.ksh.backup go.ksh go.ksh.backup

while давталт

while давталтыг ашиглах энгийн жишээг доор харуулав. i=100; while [ $i -ge 0 ] ; echo Countdown 100-аас 0 хүртэл, одоогийн утга $i; би--; хийсэн

Хязгааргүй гогцоонуудыг while true эсвэл while: мэдэгдлүүдийг ашиглан хэрэгжүүлж болно, энд тэмдэг нь: Korn shell болон bash-д байхгүй үйлдэлтэй тэнцүү байна. #!/bin/ksh # төгсгөлгүй давталт while: do echo hello sleep 1 боллоо

Давталт хүртэл

Доорх нь хүртэл давталтыг ашиглах энгийн жишээ юм. i=100; [$i -le 0] хүртэл; 100-аас 1 хүртэл цуурай Countdown хийх, одоогийн утга $i; би--; хийсэн

Дадлага: Скрипт дэх тест ба гогцоо

3. 3-аас 7 хүртэл тоолохдоо while давталт ашиглах скрипт боловсруул.

4. 8-аас 4 хүртэл тоолохдоо хүртэл давталт ашиглах скрипт боловсруул.

5. Одоогийн директор доторх .txt өргөтгөлтэй файлуудыг тоолох скрипт боловсруул.

6. Хэрэв одоогийн директор дотор .txt өргөтгөлтэй файл байхгүй бол түүнийг зөв ажиллуулахын тулд үүсгэсэн скрипт дэх if хэллэгийг ашиглана уу.

Практик даалгаврыг гүйцэтгэх зөв журам: скрипт дэх шалгалт, гогцоо

1. 3-аас 7 хүртэл тоолохдоо for гогцоо ашиглах скрипт боловсруул.

#!/bin/bash for i in 3 4 5 6 7 do echo 3-аас 7 хүртэл тоолох, одоогийн утга $i хийгдсэн

2. 1-ээс 17000 хүртэл тоолохын тулд for циклийг ашиглах скрипт боловсруул.

Bash бүрхүүл нь утгын дарааллыг давтах боломжийг олгодог гогцоонуудыг дэмждэг. Ийм л байна үндсэн бүтэцийм мөчлөгүүд:

Жагсаалтанд байгаа var командыг гүйцэтгэнэ
Давталтын давталт бүрт var хувьсагч дараахаас дараагийн утга руу бичигдэнэ жагсаалт. Тиймээс давталтын эхний дамжуулалт нь жагсаалтын эхний утгыг ашиглана. Хоёр дахь нь - хоёр дахь, гэх мэт - гогцоо нь сүүлчийн элементэд хүрэх хүртэл.

Энгийн утгуудыг давтах

Магадгүй bash скрипт дэх for давталтын хамгийн энгийн жишээ бол энгийн утгуудын жагсаалтыг давтах явдал юм.

#!/bin/bash for var in first second three fourth fifth do echo $var зүйл дууссан
Энэ скриптийн үр дүнг доор харуулав. $var хувьсагч нь жагсаалтын элементүүдийг дараалан агуулж байгааг та тодорхой харж болно. Энэ нь мөчлөг нь сүүлчийнх нь хүрэх хүртэл тохиолддог.


Энгийн for loop

$var хувьсагч нь давталтаас гарахад утгаа хадгалдаг, агуулгыг нь өөрчлөх боломжтой, ерөнхийдөө та бусад хувьсагчтай адил түүнтэй ажиллах боломжтой гэдгийг анхаарна уу.

Нарийн төвөгтэй утгуудыг давтах

For давталтыг эхлүүлэхэд хэрэглэгдэх жагсаалт нь зөвхөн нэг үгээс бүрдсэн энгийн мөрүүд төдийгүй хэд хэдэн үг, цэг таслал агуулсан бүхэл бүтэн хэллэгийг агуулж болно. Жишээлбэл, энэ нь иймэрхүү харагдаж болно:

#!/bin/bash-д зориулсан var эхний "хоёр дахь" "гурав дахь" "Би үүнийг хийнэ" гэсэн цуурай хийх "Энэ бол: $var" хийсэн.
Энэ гогцоо жагсаалтаар дамжсаны дараа ийм зүйл тохиолддог. Таны харж байгаагаар үр дүн нь нэлээд хүлээгдэж байна.


Нарийн төвөгтэй утгуудыг давтах
TNW-CUS-FMP - манай үйлчилгээнд 10% хөнгөлөлт үзүүлэх сурталчилгааны кодыг 7 хоногийн дотор идэвхжүүлэх боломжтой"

Тушаалын үр дүнгээс олж авсан жагсаалт бүхий давталтыг эхлүүлж байна

For давталтыг эхлүүлэх өөр нэг арга бол түүнд тушаалын үр дүн болох жагсаалтыг дамжуулах явдал юм. Энд командын орлуулалт нь тэдгээрийг гүйцэтгэх, ажлын үр дүнг авахад ашиглагддаг.

$(cat $file) доторх var-д зориулсан #!/bin/bash file="myfile" "$var"-г дуусна
Энэ жишээ нь файлын агуулгыг уншдаг cat командыг ашигладаг. Үр дүнгийн утгуудын жагсаалтыг гогцоонд дамжуулж, дэлгэц дээр харуулна. Бидний хандаж буй файл нь шинэ мөрөөр тусгаарлагдсан үгсийн жагсаалтыг агуулж байгааг анхаарна уу.


Файлын агуулгыг давах гогцоо

Хэрэв мөр мөрөөр өгөгдөл боловсруулах гэж байгаа бол ийм арга нь илүү төвөгтэй бүтэцтэй файлд ажиллахгүй бөгөөд мөр нь хоосон зайгаар тусгаарлагдсан хэд хэдэн үг агуулж болно гэдгийг энд бид анхаарч үзэх хэрэгтэй. Гогцоо нь мөр биш, харин бие даасан үгсийг боловсруулах болно.

Хэрэв энэ нь танд огт хэрэггүй бол яах вэ?

Талбайн тусгаарлагч

Дээрх шинж чанарын шалтгаан нь онцгой юм орчны хувьсагч, үүнийг IFS (Internal Field Separator) гэж нэрлэдэг бөгөөд талбар тусгаарлагчийг зааж өгөх боломжийг олгодог. Анхдагч байдлаар, bash бүрхүүл нь дараах тэмдэгтүүдийг талбар тусгаарлагч гэж үздэг.
  • Орон зай
  • Таб тэмдэг
  • Мөр тэжээлийн тэмдэгт
Хэрэв bash нь өгөгдөлд эдгээр тэмдэгтүүдийн аль нэгтэй нь тааралдвал жагсаалтын дараагийн бие даасан утга өмнө нь байна гэж үздэг.

Асуудлыг шийдэхийн тулд та IFS орчны хувьсагчийг түр хугацаанд өөрчилж болно. Талбар тусгаарлагчийн хувьд зөвхөн шинэ мөр хэрэгтэй гэж үзвэл bash скрипт дээр үүнийг хэрхэн хийхийг эндээс үзнэ үү:

IFS=$"\n"
Энэ командыг bash скриптдээ нэмсний дараа энэ нь хоосон зай, табуудыг үл тоомсорлож, зөвхөн шинэ мөрийн тэмдэгтүүдийг талбар тусгаарлагч болгон авч үзсэний дагуу ажиллах болно.

#!/bin/bash file="/etc/passwd" $(cat $file) доторх var-д IFS=$"\n" " $var"-г дууслаа.
Хэрэв энэ скриптийг ажиллуулбал энэ нь яг юу шаардагдахыг гаргаж, давталтын давталт бүрт файлд бичигдсэн дараагийн мөрөнд хандах боломжийг олгоно.


For давталт дахь файлыг мөр мөрөөр шилжүүлэх

Тусгаарлагч нь бусад дүрүүд байж болно. Жишээлбэл, дээр бид /etc/passwd файлын агуулгыг харуулсан. Мөр дээрх хэрэглэгчийн өгөгдлийг хоёр цэгээр тусгаарлана. Хэрэв та ийм мөрүүдийг давталтаар боловсруулах шаардлагатай бол IFS-ийг дараах байдлаар тохируулж болно.

Лавлахад байгаа файлуудыг шилжүүлэх

Bash скрипт дэх for давталтын хамгийн түгээмэл хэрэглээний нэг бол директор дотор байрлах файлуудыг гүйлгэж тэдгээр файлуудыг боловсруулах явдал юм.

Жишээлбэл, файл, хавтсыг хэрхэн жагсаах талаар эндээс үзнэ үү.

/home/likegeeks/* доторх файлын хувьд #!/bin/bash хийвэл [ -d "$file" ] байвал "$файл бол директор" elif [ -f "$file" ] гэсэн цуурай дараа "$файл бол a файл" хийж дуусгалаа
Хэрэв та энэ цуврал нийтлэлийн өмнөх материалыг ойлгосон бол if-then-ийн бүтэц, мөн файлыг хавтаснаас хэрхэн ялгах талаар ойлгох хэрэгтэй. Хэрэв та дээрх кодыг ойлгоход хэцүү байвал энэ материалыг дахин уншина уу.

Энэ бол скриптээс гарах зүйл юм.


Фолдерын агуулгыг харуулж байна

Бид гогцоог хэрхэн эхлүүлэхэд анхаарлаа хандуулаарай, тухайлбал орлуулагч тэмдэг"*" хавтас хаягийн төгсгөлд байна. Энэ тэмдгийг "ямар ч нэртэй бүх файлууд" гэсэн утгатай орлуулагч тэмдэг гэж үзэж болно. зохион байгуулах боломжийг танд олгоно автомат орлуулалтзагварт тохирсон файлын нэрс.

if командын нөхцөлийг шалгахдаа бид хувьсагчийн нэрийг хашилтанд оруулдаг. Файл эсвэл хавтасны нэр нь хоосон зай агуулж болзошгүй тул үүнийг хийсэн болно.

Гогцоонд зориулсан C-загвар

Хэрэв та C програмчлалын хэлийг мэддэг бол гогцоонуудыг тайлбарлахдаа bash for loop-ийг тайлбарлах синтакс танд хачирхалтай санагдаж магадгүй, учир нь та гогцоонуудыг ингэж тайлбарлаж дассан нь ойлгомжтой.

Учир нь (i = 0; i< 10; i++) { printf("number is %d\n", i); }
Bash скриптүүдэд та for loops ашиглаж болно, тайлбар нь C загварын гогцоотой маш төстэй харагддаг боловч зарим ялгаа байдаг. Энэ аргын мөчлөгийн диаграмм дараах байдалтай байна.

For ((хувьсагчийн анхны утга; төгсгөлийн давталтын нөхцөл; хувьсагчийн өөрчлөлт))
Bash дээр үүнийг дараах байдлаар бичиж болно.

Учир нь ((a = 1; a< 10; a++))
Ажлын жишээ энд байна:

#!/bin/bash ((i=1; i<= 10; i++)) do echo "number is $i" done
Энэ код нь 1-ээс 10 хүртэлх тооны жагсаалтыг гаргах болно.

С хэв маягаар давталт хийх

while давталт

For бүтэц нь bash скрипт дэх гогцоонуудыг зохион байгуулах цорын ганц арга биш юм. Та энд мөн while давталтыг ашиглаж болно. Ийм гогцоонд та тодорхой нөхцөлийг шалгах командыг зааж өгч, шалгагдаж буй нөхцөл тэг болох хүртэл давталтын биеийг гүйцэтгэх эсвэл тодорхой үйлдлийг амжилттай дуусгах дохиог өгч болно. Давталтын нөхцөл нь тэгээс өөр утгыг буцаавал алдаа гарлаа гэсэн үг бол давталт зогсох болно.

while давталтын зохион байгуулалтын диаграммыг энд үзүүлэв
нөхцөл шалгах команд
хийх
бусад багууд
хийсэн

Ийм гогцоотой жишээ скриптийг харцгаая.

#!/bin/bash var1=5 байхад [ $var1 -gt 0 ] echo $var1 var1=$[ $var1 - 1 ] дууссан
Давталтын үүдэнд $var1 хувьсагч тэгээс их эсэхийг шалгана. Хэрэв тийм бол хувьсагчийн утгаас нэгийг нь хассан давталтын биеийг гүйцэтгэнэ. Энэ нь давталт бүрт тохиолддог бөгөөд бид хувьсагчийн утгыг өөрчлөхөөс өмнө консол дээр хэвлэдэг. $var1 0 утгад хүрмэгц гогцоо зогсоно.

while давталтын үр дүн

Хэрэв та $var1 хувьсагчийг өөрчлөхгүй бол энэ нь скриптийг төгсгөлгүй давталтад хүргэх болно.

Оруулсан гогцоо

Та давталтын үндсэн хэсэгт байгаа дурын командыг ашиглаж болно, үүнд бусад давталтыг эхлүүлэх боломжтой. Ийм бүтээцийг үүрлэсэн гогцоо гэж нэрлэдэг.

#!/bin/bash ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
Энэ скриптээс юу гарахыг доор харуулав. Таны харж байгаагаар эхлээд гаднах гогцооны эхний давталт, дараа нь дотоод давталтын гурван давталт хийгдэж, дууссаны дараа гаднах гогцоо дахин, дараа нь дотоод давталт гарч ирнэ.

Оруулсан гогцоо

Файлын агуулгыг боловсруулж байна

Ихэнх тохиолдолд файлуудыг боловсруулахад үүрлэсэн гогцоо ашигладаг. Тиймээс гаднах гогцоо нь файлын мөрүүдийг давтаж байгаа бөгөөд дотоод нь мөр бүртэй аль хэдийн ажиллаж байна. Жишээлбэл, /etc/passwd файлыг боловсруулахад дараах байдалтай байна.

#!/bin/bash IFS=$"\n" $(cat /etc/passwd)-д оруулах "Values ​​in $entry –" IFS=: "$entry дахь утгыг" цуурай хийх " $value" хийгдсэн хийсэн
Энэ скриптэд хоёр гогцоо байна. Эхнийх нь шинэ мөрийн тэмдэгтийг хязгаарлагч болгон ашиглан мөрүүдийг гатлана. Дотоод талбарууд нь хоёр цэгээр тусгаарлагдсан мөрүүдийг задлан шинжлэхэд завгүй байдаг.

Файлын өгөгдөл боловсруулах

Энэ аргыг CSV файлууд эсвэл ижил төстэй файлуудыг боловсруулахад шаардлагатай бол IFS орчны хувьсагч руу тусгаарлах тэмдэгтийг бичих замаар ашиглаж болно.

Циклийн менежмент

Магадгүй, гогцоонд орсны дараа давталтын хувьсагч нь давталтыг дуусгах анх заасан нөхцөлтэй тохирохгүй тодорхой утгад хүрэх үед үүнийг зогсоох шаардлагатай болно. Ийм нөхцөлд мөчлөг хэвийн дуусах хүртэл хүлээх шаардлагатай юу? Мэдээжийн хэрэг үгүй, ийм тохиолдолд дараах хоёр тушаал хэрэг болно.
  • завсарлага
  • үргэлжлүүл

таслах тушаал

Энэ команд нь давталтын гүйцэтгэлийг таслах боломжийг олгоно. Үүнийг for болон while аль алинд нь ашиглаж болно:

1 2 3 4 5 6 7 8 9 10 дотор var1-д зориулсан #!/bin/bash хий, хэрэв [ $var1 -eq 5 ] бол fi echo "Дугаар: $var1" дууссан
Ийм гогцоо нь ердийн нөхцөлд жагсаалтын утгуудын жагсаалтыг бүхэлд нь дамжих болно. Харин манай тохиолдолд $var1 хувьсагч 5-тай тэнцүү байх үед түүний гүйцэтгэл тасалдана.

For давталтаас эрт гарч байна

Энд ижил зүйл байна, гэхдээ while циклийн хувьд:

#!/bin/bash var1=1 байхад [ $var1 -lt 10 ] хийвэл, хэрэв [ $var1 -eq 5 ] бол fi echo "Давталт: $var1" var1=$(($var1 + 1)) дууссан
$var1 5 хүрэх үед гүйцэтгэсэн завсарлага команд нь давталтыг тасалдаг. Консол нь өмнөх жишээн дээрхтэй ижил зүйлийг харуулах болно.

үргэлжлүүлэх тушаал

Энэ команд давталтын үндсэн хэсэгт таарвал одоогийн давталт эрт дуусч дараагийнх нь давтахаас гарахгүйгээр эхэлнэ. For давталт дахь үргэлжлүүлэх командыг харцгаая:

#!/bin/bash ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
Давталтын доторх нөхцөл хангагдсан үед, өөрөөр хэлбэл $var1 нь 5-аас их, 10-аас бага үед бүрхүүл нь үргэлжлүүлэх командыг гүйцэтгэдэг. Энэ нь давталтын үндсэн хэсэгт үлдсэн командуудыг алгасаад дараагийн давталт руу шилжихэд хүргэдэг.

For давталт дахь үргэлжлүүлэх тушаал

Боловсруулалтын гаралтыг давталтаар ажиллуулж байна

Давталтын өгөгдлийн гаралтыг гаралтыг дахин чиглүүлэх эсвэл дамжуулах хоолой руу дамжуулах замаар боловсруулж болно. Энэ нь гүйцэтгэсэн мэдэгдлийн дараа гаралтыг боловсруулах командуудыг нэмэх замаар хийгддэг.

Жишээлбэл, та давталтаар юу гарч байгааг дэлгэц дээр харуулахын оронд бүгдийг нь файл руу бичиж эсвэл өөр газар дамжуулж болно.

#!/bin/bash ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt echo "дууссан."
Бүрхүүл нь myfile.txt файлыг үүсгэж, for мэдэгдлийн гаралтыг тухайн файл руу дахин чиглүүлэх болно. Файлыг нээж, яг бидний хүлээж буй зүйлийг агуулж байгаа эсэхийг шалгацгаая.

Давталтын гаралтыг файл руу дахин чиглүүлэх

Жишээ: Гүйцэтгэх боломжтой файлуудыг хайх

Нэгэнт тайлбарласан зүйлээ ашиглаад хэрэгтэй зүйл бичье. Жишээлбэл, хэрэв та систем дээр аль гүйцэтгэх боломжтой файлуудыг олж мэдэх шаардлагатай бол PATH орчны хувьсагч дээр бичигдсэн бүх хавтсыг сканнердаж болно. Бидэнд шаардлагатай бүх хэрэгслийн арсенал аль хэдийн байгаа тул бүгдийг нь цуглуулахад л хангалттай.

#!/bin/bash IFS=: $PATH доторх фолдерын хувьд "$folder:" гэсэн цуурайг $folder/* доторх файлын хувьд [ -x $file] хийвэл " $file"-г дуурайна.
Энэхүү жижиг бөгөөд энгийн скрипт нь PATH-аас хавтсанд хадгалагдсан гүйцэтгэх файлуудын жагсаалтыг авах боломжийг бидэнд олгосон.

PATH хувьсагчаас хавтсанд гүйцэтгэх боломжтой файлуудыг хайж байна

Үр дүн

Өнөөдөр бид bash скрипт дээрх for болон while гогцоо, тэдгээрийг хэрхэн ажиллуулах, хэрхэн удирдах талаар ярилцлаа. Одоо та гогцоонд янз бүрийн хязгаарлагчтай мөрүүдийг хэрхэн боловсруулах, гогцоон дахь өгөгдлийн гаралтыг файл руу хэрхэн шилжүүлэх, лавлах агуулгыг хэрхэн үзэх, шинжлэх талаар мэддэг болсон.

Хэрэв та энэ цуврал нийтлэлийн эхний хэсэг, энэ хоёр дахь хэсэгт дурдсан зүйлийг л мэддэг bash скрипт хөгжүүлэгч гэж үзвэл та аль хэдийн хэрэгтэй зүйл бичиж болно. Цаашид гурав дахь хэсэг байгаа бөгөөд үүнийг ойлгосны дараа та параметрүүдийг хэрхэн bash скрипт рүү шилжүүлэх, командын мөрийг хэрхэн шилжүүлэх, мөн үүнийг юу хийх талаар сурах болно.

Гогцооны төрлүүдийн ялгааны товч тайлбар:

for - гүйцэтгэх объект байгаа л бол үйлдлийг гүйцэтгэнэ (жишээлбэл, stdin, файл эсвэл функцээс урсгал унших);
while - хүртэл үйлдлийг гүйцэтгэдэг нөхцөлүнэн;
хүртэл - байх хугацаанд нь гүйцэтгэх болно нөхцөлүнэн болохгүй, өөрөөр хэлбэл. одоохондоо худлаа.

FOR давталт

Скриптийн энэ хувилбарыг гогцоотой авч үзье:

`ls -1` доторх хувьсагчийн $ cat loop.sh #!/bin/bash "$variable"-г цуурай хийх

Синтакс нь маш энгийн бөгөөд жишээн дээр маш тодорхой харагдаж байна:

for (хувьсагчийг эхлүүлэх) хувьсагч (бидний үйлдэл хийх хувьсагчийг зарлах) (хувьсагч руу урсгал илгээх) `ls -1` (хэрэглэх тушаалыг $variable хувьсагч руу шилжүүлэх). Do and done нь хүлээн авсан өгөгдөл дээр үндсэн үйлдлүүд хийгдэх давталтын "бие" бөгөөд echo "$variable" нь давталтын бодит үйлдэл юм.

Одоо жишээг бага зэрэг өөрчилье, командыг тодорхой зааж өгөхийн оронд бид хоёр дахь хувьсагчийг ашиглана:

$ cat loop.sh #!/bin/bash ls=`ls -1` $ls доторх хувьсагчийн хувьд "$variable"-г цуурайлган хийнэ

Одоо ls -1 командыг тусдаа хувьсагчаар дамжуулсан бөгөөд энэ нь давталттай илүү уян хатан ажиллах боломжийг олгодог. Та гогцоонд байгаа хувьсагчийн оронд функцийг ашиглаж болно:

$ cat loop.sh #!/bin/bash lsl () ( ls -1 ) `lsl` доторх хувьсагчийн хувьд "$variable"-г цуурай хийнэ үү

For давталтын гол нөхцөл нь түүнд дамжуулсан команд нь үйлдэл хийх объектуудыг агуулж байгаа л бол түүнийг гүйцэтгэх болно. Дээрх жишээн дээр үндэслэн - ls -1-д харуулах файлууд байгаа л бол гогцоо нь тэдгээрийг хувьсагч руу дамжуулж, "давталтын бие"-г гүйцэтгэнэ. Лавлах дахь файлуудын жагсаалт дуусмагц давталт нь гүйцэтгэлээ дуусгана.

Жишээг арай илүү төвөгтэй болгоё.

Сан нь файлуудын жагсаалтыг агуулна:

$ ls -1 файл1 файл2 файл3 файл4 файл5 loop.sh nofile1 nofile2 nofile3 nofile4 nofile5

Бид тэднээс зөвхөн үг байхгүй хүмүүсийг сонгох хэрэгтэй. үгүй«:

$ cat loop.sh #!/bin/bash lsl=`ls -1` $lsl дахь хувьсагчийн хувьд do echo "$variable" | grep -v "үгүй" хийсэн $ ./loop.sh файл1 файл2 файл3 файл4 файл5 loop.sh

Та мөн нөхцөлт илэрхийллийг давталтад ашиглаж болно ( нөхцөлт илэрхийллүүд) […] нөхцөлийг шалгах, хэрэв нөхцөл үүсвэл давталтыг таслах завсарлага.

Энэ жишээг авч үзье:

$ cat loop.sh #!/bin/bash lsl=`ls -1` $lsl дахь хувьсагчийн хувьд do if [ $variable != "loop.sh" ] дараа нь "$variable"-ийн цуурай | grep -v "үгүй" эс бөгөөс fi дууссан

Loop.sh файлтай тулгарах хүртэл давталт үргэлжлэх болно. Давталтын гүйцэтгэл энэ файлд хүрмэгц завсарлага командаар давталт таслагдах болно.

$ ./loop.sh файл1 файл2 файл3 файл4 файл5

Өөр нэг жишээ бол давталтын биеийг гүйцэтгэхийн өмнө шууд арифметик үйлдлүүдийг ашиглах явдал юм.

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

Энд бид гурван хяналтын командыг тохируулсан - тоо = 1, хяналтын нөхцөл - тоо 11-ээс бага байх үед, гүйцэтгэх тушаал - тоолох +1:

WHILE ба Util гогцоонууд

while давталт хэрхэн ажилладагийг тодорхой харуулсан энгийн жишээ:

$ cat loop.sh #!/bin/bash count=0 байхад [ $count -lt 10 ] хийх ((count++)) echo $count хийгдсэн

Бид $count хувьсагчийг тэг болгож, дараа нь "$count нь араваас бага байхад давталтыг гүйцэтгэнэ" гэсэн нөхцөлтэйгээр whi le циклийг ажиллуулна. Гогцооны биед бид гүйцэтгэдэг постфиксийн өсөлт$count хувьсагч руу +1, үр дүнг stdout дээр хэвлэнэ.

Гүйцэтгэлийн үр дүн:

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

$count хувьсагчийн утга 10 болмогц давталт зогссон.

while хэрхэн ажилладагийг харуулсан "хязгааргүй" гогцооны сайн жишээ:

$ cat loop.sh #!/bin/bash count=10 байхад [ 1 = 1 ] хийх ((тоо++)) цуурай $тоо хийсэн $ ./loop.sh ... 5378 5379 5380 5381 5382 5383 ^C

хүртэл давталт ижил төстэй, гэхдээ эсрэг чиглэлд ажилладаг:

$ cat loop.sh #!/bin/bash count=0 хүртэл [ $count -gt 10 ] хийх ((count++)) echo $count дууссан

Энд бид ижил төстэй нөхцөлийг тавьсан боловч "хувьсагч 10-аас бага байх үед"-ийн оронд "хувьсагч 10-аас их болтол"-ыг зааж өгнө. Гүйцэтгэлийн үр дүн:

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

Хэрэв дээрх "эцэс төгсгөлгүй давталт"-ын жишээг хүртэл ашиглан гүйцэтгэсэн бол while-аас ялгаатай нь юу ч гаргахгүй.

$ cat loop.sh #!/bin/bash count=10 хүртэл [ 1 = 1 ] хийх ((тоо++)) цуурай $тоо хийсэн $ ./loop.sh $

Учир нь " нөхцөл"анх" үнэн"- гогцооны биеийг гүйцэтгэхгүй.

For давталттай адил while болон хүртэл функцуудыг ашиглаж болно. Жишээлбэл, серверийн статусыг шалгадаг бодит скриптийн гогцоо Том муур(PID-г системээс авсан SLES, бусад системд ялгаатай байж болно), бага зэрэг хялбаршуулсан хувилбар:

$ cat loop.sh #!/bin/bash check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "($2 хэвлэх)"` ) байхад check_tomcat_status нь хэрэв [ -n "$ байвал хийнэ үү. RUN" ] дараа нь printf "АНХААРУУЛГА: Tomcat PID $RUN-оор ажиллаж байна." else printf "Tomcat зогссон, үргэлжлүүлж байна...nn" завсарлага дууссан

Гүйцэтгэлийн үр дүн:

$ ./loop.sh АНХААРУУЛГА: Tomcat PID 14435 26548-тай ажиллаж байна. АНХААРУУЛГА: Tomcat PID 14435 26548-тай ажиллаж байна. АНХААРУУЛГА: Tomcat PID 14435 26548-тай ажиллаж байна. АНХААРУУЛГА: Tomcat Tomcat PID1445AR-тай ажиллаж байна. PID 14435 26548-тай ажиллаж байна. АНХААРУУЛГА: Tomcat PID 14435 26548-тай ажиллаж байна. АНХААРУУЛГА: Tomcat PID 14435 26548-тай ажиллаж байна. АНХААРУУЛГА: Tomcat PID 14435-тай ажиллаж байна.

Бүрэн хувилбар:

Check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(2$ хэвлэх)"` ) check_tomcat_status үед; do if [ -n "$RUN" ] then printf "АНХААРУУЛГА: Tomcat PID $RUN-оор ажиллаж байна. Үүнийг зогсоох уу? " гэж хариулах "Tomcat-г зогсоож байна..." "Суулгацыг үргэлжлүүлж байна..." && $CATALINA_HOME/bin/shutdown sh 2&>1 /dev/null || Хэрэв [ -n "$RUN" ] бол унтах 2-ыг таслана, дараа нь printf "Tomcat ажиллаж байна. Алах уу? " гэж хариулах "Tomcat-ыг устгаж байна уу..." "Суулгацыг үргэлжлүүлж байна...n" && $RUN || завсарлага унтах 2 fi else printf "Tomcat зогссон, үргэлжлүүлж байна...nn" завсарлах fi дууссан

Хариултын функцийг нийтлэлд тайлбарласан боловч энд бага зэрэг сайжруулсан хувилбарыг ашигласан болно.

Хариулт () (хариултыг уншиж байх үед; echo case $response in |) printf "$1n" буцаах 0 завсарлага;; |) printf "$2n" 1 завсарлага буцаана;; *) printf "Y(тийм) эсвэл N(үгүй) гэж оруулна уу!" esac хийгдсэн )

Энд while болон хүртэл хоёуланг нь ашиглах боломжтой байсан - гэхдээ for давталт биш, учир нь for нь нэг удаа ажиллах байсан (PID хүлээн аваад дууссан).

Гогцоонууд нь ямар ч програм эсвэл скрипт бичихэд маш тохиромжтой, бүр зайлшгүй шаардлагатай зүйл юм. Тэд бидэнд кодын тодорхой хэсгийг хэдэн удаа гүйцэтгэх боломжийг олгодог. Мэдээжийн хэрэг, bash нь хэд хэдэн төрлийн гогцоотой байдаг. Бид мөчлөгийг тайлбарлах болно for in, for, while, until. Хэдийгээр for болон for нь ижил хэллэгийн өөр өөр синтакс гэж тооцогддог боловч миний бодлоор тэд бие биенээсээ while-аас илүү ялгаатай байдаг.

Дотор нь тоологчтой гогцоо:

Цикл хувьдЭнэ бол тоолууртай гогцоо юм. Давталтын биед байрлах кодын блок нь for in операторын жагсаалтад байгаа утгуудын хэрээр олон удаа давтагддаг бөгөөд давталт бүрт тоолуур хувьсагч (энд үүнийг var гэж нэрлэдэг, гэхдээ мэдээжийн хэрэг) та үүнийг хүссэнээрээ дуудаж болно) жагсаалтын дараагийн элементийн утгатай байна.
Хэрэв do гэсэн түлхүүр үг нь төлөө гэсэн үгтэй нэг мөрөнд байгаа бол аргументуудын жагсаалтын ард (do хийхээс өмнө) цэгтэй таслал тавих ёстой.
Элемент бүр<список>хэд хэдэн аргумент агуулж болно. Энэ нь параметрийн бүлгүүдийг боловсруулахад хэрэгтэй. Энэ тохиолдолд аргумент тус бүрийг задлан шинжлэхийг албадах хэрэгтэй<списке>, та тогтоосон зааврыг ашиглах ёстой
Та хувьсагчийг for циклд жагсаалт болгон ашиглаж болно.
IN<списке>For давталт нь файлын нэрийг ашиглаж болох бөгөөд энэ нь эргээд орлуулагч тэмдэгтүүдийг агуулж болно. Энэ нь олон тооны файлуудтай ажиллахад маш хэрэгтэй байж болох юм.
Хэрэв<список>for циклд заагаагүй бол $@ хувьсагчийг командын мөрийн аргументуудын жагсаалт болгон ашигладаг.
Аргументуудын жагсаалтыг гаргахдаа for циклд командын орлуулалтыг ашиглаж болно.
Давталтын гаралтыг stdout-аас файл руу эсвэл өөр газар руу чиглүүлж болно (та I/O дахин чиглүүлэлтээс энэ талаар илүү ихийг мэдэж болно).

Синтакс:
for var in<список>
хийх
<выполняемые команды>
хийсэн

Жишээ:
нэрийн хувьд1 нэр2 нэр3 нэр4
хийх
цуурай $ нэрс
хийсэн

Давталтын оператор төлөөбичих өөр аргатай - Си хэл дээрх for операторын синтакстай маш төстэй. Энэ тохиолдолд тоолуурыг эхлүүлэх үед хувьсагчийн анхны утгууд эсвэл нэг хувьсагчийн утгыг тохируулах ба давталт бүрийн дараа нөхцөлийг тохируулдаг. шалгагдсан, хэрэв шалгалт үнэн гэж буцвал давталтын дараагийн дамжуулалт эхэлнэ. Блок дотор<приращение счётчиков>Манай хувьсагчийн тоологчийн утга заавал өөрчлөгдөх ёстой (дээш биш) ингэснээр нөхцөлийг шалгахдаа эрт орой хэзээ нэгэн цагт бид худал утгыг авах болно, эс тэгвээс давталт хэзээ ч дуусахгүй. Аливаа үйлдлийг хэд хэдэн удаа давтах шаардлагатай бол маш тохиромжтой бөгөөд хамгийн чухал нь танил сонголт.

Үүнтэй төстэй синтакстай:
төлөө ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
хийх
<выполняемые команды>
хийсэн

Жишээ:
төлөө ((var=1; var<= LIMIT ; var++))
хийх
echo $var
хийсэн

while давталт:

Энэ нь операторын ард байгаа нөхцөл байдлыг шалгадаг нэлээд энгийн бүтэц юм байхадхэрэв энэ нөхцөл үнэн бол do, done гэсэн үгсийн хооронд байрлах командын блокийг гүйцэтгээд нөхцөлийг дахин шалгана. Хэрэв шалгалт худал гэж хариулбал мөчлөг дуусч, дараах тушаалуудыг гүйцэтгэж эхэлнэ. хийсэн. Үүнийг баталгаажуулах нь зайлшгүй юм<проверка условия>Энэ нь гогцоонд ажиллаж буй кодоос хамаарна, эс тэгвээс шалгалтын үр дүн өөрчлөгдөхгүй бол та хязгааргүй давталт авах болно.
Хэсэг хугацааны давталтын стандарт оролтын төхөөрөмжийг дахин чиглүүлэх командыг ашиглан файл руу дахин чиглүүлэх боломжтой< в конце цикла.

Синтакс:
байхад<Проверка условия>
хийх
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
хийсэн

Жишээ:
байхад [ $var0 -eq 100 ]
хийх
echo $var
var++
хийсэн

Оператор байхадхэд хэдэн нөхцөл байж болно. Гэхдээ зөвхөн сүүлчийнх нь мөчлөгийг үргэлжлүүлэх боломжийг тодорхойлдог. Энэ тохиолдолд давталтын операторын синтакс нь ердийнхөөс өөр байх болно.
Синтакс(Зөвхөн сүүлчийн нөхцөл нь давталтын гүйцэтгэлд нөлөөлдөг гэдгийг би дахин давтан хэлье) :
байхад
<условие1>
<условие2>

<условиеN>
хийх
<выполняемые команды - тело цикла>
хийсэн

Давталт хүртэл:

Оператор хүртэл while-тай маш төстэй, мөн нөхцөлийг үнэлдэг боловч тооцооллын үр дүн худал бол давталтын биеийг гүйцэтгэдэг. Энэ нь ер бусын мэт санагдаж болох ч давталтын эхний дамжуулалтын өмнөх нөхцөл байдлыг үнэлэх хүртэл, дараа нь биш while гэх мэт. For/in гогцоонуудын нэгэн адил do түлхүүр үгийг давталтын мэдэгдэлтэй нэг мөрөнд байрлуулахдаа ";" тэмдэгт оруулах ёстой. хийхээс өмнө.
Өмнөх тохиолдлын нэгэн адил нөхцөл нь давталтын бие дэх үйлдлээс хамаарах ёстой гэдгийг санах нь чухал бөгөөд эс тэгвээс бидний скрипт хэзээ ч дуусахгүй.

Синтакс:
хүртэл<Проверка условия>
хийх
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
хийсэн

Жишээ:
хүртэл [ $var0 -gt 100] # Нөхцөлийг давталтын эхэнд шалгана.
хийх
echo $var
var--
хийсэн

Энэ нь одоохондоо хангалттай байх. :)

  • Буцах
  • Урагшаа

Шинэ нийтлэлүүд:

  • Windows 7/8/2008/2012 дээр сүлжээний нээлт асахгүй байна
  • Алдаа: Энэ програм нь "windows" Qt платформ залгаасыг олж эсвэл ачаалж чадаагүй тул эхлүүлж чадсангүй.
  • 1С 8.3 сервер дээр rphost.exe ажилчны процессыг автоматаар дахин эхлүүлэх тохиргоог хийж байна
  • MS SQL 2008/20012 дээрх гүйлгээний бүртгэлийн (.ldf) хэмжээг хэрхэн багасгах вэ

    MS SQL нь аливаа аж үйлдвэрийн DBMS-ийн нэгэн адил мэдээллийн баазын хамт гүйлгээний бүртгэлийг хөтөлдөг бөгөөд энэ нь танд төлөвийг буцаах боломжийг олгодог ...

0 Миран Бала-Кумаран

Би яагаад энэ while давталт хэзээ ч дуусдаггүй, давталт эхлэхэд миний LOC хувьсагч Testing/ гэж тохируулагдсаныг ойлгохыг үнэхээр хичээж байна. Энэ програмыг туршихын тулд миний үүсгэсэн лавлах нь дараах бүтэцтэй байна:

Бүх лавлахуудад "тоолох" функц хэрэгжсэний дараа би давталт дуусахыг хүсч байна.
Энд би оролдсон зүйл байна;

Би тоолох функцийг шалгасан бөгөөд энэ нь хязгааргүй давталт үүсгэдэггүй

Би алгоритмыг гараар ажиллуулахыг оролдсон

PARSE=1 LOC=$LOC/ тоолох AVAILABLEDIR=$(ls $LOC -AFl | sed "1 d" | grep "/$" | awk "( хэвлэх $9 )") байхад [ $PARSE = "1" ] хийх бол [[ $(БОЛГОЖ БАЙНА [@]) == "" ]]; дараа нь $-д PARSE=0 fi DIRBASE=$LOC (AVAILABLEDIR[@]); хийх LOC="$(DIRBASE)$(a)" LOCLIST="$LOCLIST $LOC" нь $(LOCLIST[@]) дотор хийгдсэн тоо; хийх TMPAVAILABLEDIR=$(ls $a -AFl | sed "1 d" | grep "/$" | awk "( $9 )" хэвлэх) PREPEND=$a хэрэв [[ $(TMPAVAILABLEDIR[@]) == "" ] ]; дараа нь $(TMPAVAILABLEDIR[@])-д fi-г үргэлжлүүлнэ; хийх TMPAVAILABLEDIR2="$TMPAVAILABLEDIR2 $(PREPEND[@])$(a)" хийсэн NEWAVAILABLEDIR="$NEWAVAILABLEDIR $TMPAVAILABLEDIR2" хийсэн AVAILABLEDIR=$NEWAVAILABLEDIR NEWAVAILABLEDIR="" LOC="" хийсэн

Би үнэхээр хэцүү байна, ямар ч оролт нь маш их талархах болно, би сүүлийн хоёр цагийн турш үүнийг ойлгохыг хичээж байна.

bash хязгааргүй давталт

4 хариулт

Та скриптийг -x аргументаар ажиллуулах эсвэл эхний мөрөнд бичихийг оролдох хэрэгтэй:

#!/bin/bash -x

Дараа нь тэр хийдэг бүх зүйлээ хэлдэг.

Энэ тохиолдолд та хоёр алдааг анзаарч болно:

    Та TMPAVAILABLEDIR2-г хэзээ ч дахин ачаалахгүй

    Та мөн энгийн файлууд дээр ls хийдэг.

Хэрэв та рекурс хийхээс үнэхээр зайлсхийх хэрэгтэй бол рекурс хийхгүйгээр үүнийг туршаад үзээрэй:

#!/bin/bash count() ( "$1" тоолох цуурай ) todo=(Тест хийж байна) $(#todo[@]) != 0 do doit=("$(todo[@])") todo= () "$(doit[@])" доторх dir бол "$dir"/* дотор оруулахын тулд хийнэ үү # хэрэв dir хоосон бол "*" нэртэй оруулгыг харуулна do test -e "$entry" || үргэлжлүүлэх # хоосон dir count-ын "*" оруулгыг алгасах "$entry" тест -d "$entry" || үргэлжлүүлэх todo+=("$entry") хийж дууссан

Гэсэн хэдий ч та яагаад рекурсийг ашиглаж чадахгүй байгааг надад хэлээч? Энэ ямар нэгэн харшил мөн үү? Тангараглах уу? Таны амьдардаг газарт рекурсив программ хангамжийн эсрэг орон нутгийн хууль байдаг уу?

Та бүх зүсэлт дээр "тоо" хийхийг хүсч байгаагаа бичсэн. Хайлтын сонголтуудыг шалгана уу:

$LOC -type d |-г олоорой найруулгыг уншиж байхдаа; do cd $LOC cd $(дир) хийсэн тоо

эсвэл богино (таны функцын тоолуур лавлахыг 1-р параметр болгон авах үед)

$LOC -type d |-г олоорой xargs тоолно

Одоо би таныг find эсвэл ls -R (рекурсив функц) ашиглахыг хүсэхгүй байгааг харж байна. Дараа нь та өөрийн рекурсив функцийг хийх хэрэгтэй

parseDir функц ( ls -d */ $1 | dir унших үед; parseDir $1/$dir хийгдсэн гэж тоолно уу)

Энэ нь ажиллах эсэхийг би мэдэхгүй, гэхдээ энэ бол миний бодлоос салж чадаагүй сонирхолтой асуулт юм. Амжилт хүсье

Үнэн боловч; "$(echo *)" дотор үгээр хийх; хэрэв [[ -d "$word" ]] хийх; дараа нь d[$((i++))]="$PWD"/"$ үг" elif [[ -f "$ үг" ]] ;дараа нь f[$((j++))]="$PWD"/"$ үг" fi хийсэн [[ $k -gt $i ]] && cd .. cd "$d[$((k++))]" || завсарлага дууссан