Яагаад for цикл директор дээр ажиллахгүй байна вэ? Яагаад bash скриптүүдийн Loops санд 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 файл" хийж дуусгалаа

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 (Дотоод талбар тусгаарлагч) хэмээх тусгай орчны хувьсагч юм. Анхдагч байдлаар, 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 завсарлага;;

5

|) printf "$2n" 1 завсарлага буцаана;;

*) printf "Y(тийм) эсвэл N(үгүй) гэж оруулна уу!" esac хийгдсэн )

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

1) Таны скрипт аюултай байдлаар кодлогдсон байна. Нэгдүгээрт, та "/bash" болон "/for" гэж тэмдэглэсэн тул Bash бүрхүүлийг ашиглаж байна гэж би бодож байна.Хариулахдаа би Bash сурах хамгийн сайн эх сурвалж болох энэхүү гайхалтай Bash гарын авлагыг иш татах болно.

Тодруулбал, $(find$ DIRWORK -type d -name ажил) болон $(find$ DIR -type f) нь Word Splitting-д хамрагдах тул хэрэв find өөрийн нэрэн дэх хоосон зайтай файлыг, өөрөөр хэлбэл "файлын нэр"-ийг олвол үгийг хуваах үр дүн Bash нь дахин давтагдахын тулд for команд руу 2 аргумент дамжуулна, өөрөөр хэлбэл нэг нь "файл", нөгөө нь "нэр". Энэ тохиолдолд та "файл: ийм файл эсвэл лавлахгүй" болон "нэр: тийм файл эсвэл лавлах байхгүй" гэсэн мэдээллийг авна гэж найдаж байна, гэхдээ тэдгээр нь үнэхээр байгаа бол гэмтээж болзошгүй.

2) Дүрмээр бол орчны хувьсагч (PATH, EDITOR, SHELL, ...) болон дотоод бүрхүүлийн хувьсагчдыг (BASH_VERSION, RANDOM, ...) бүрэн том үсгээр бичдэг. Бусад бүх хувьсагчийн нэр жижиг үсгээр бичигдсэн байх ёстой. Хувьсагчийн нэрс нь жижиг жижиг жижиг үсгээр ялгагддаг тул энэхүү конвенци нь хүрээлэн буй орчны болон дотоод хувьсагчдыг санамсаргүй байдлаар дарж бичихээс зайлсхийдэг.

Энэ бол таны скриптийн аюулгүй хувилбар бөгөөд оронд нь ашиглахыг зөвлөж байна:

My_home="/root/mydir" my_dir=" $my_home/var" dir_work="$ my_home/Local" байхад IFS= унших -r -d "" f; do # Би чамайг бас stderr-ийг үл тоомсорлохыг хүсч байна гэж таамаглаж байна; # эндээс 2>&1 гарч ирсэн. if lsof -n "$f" | grep "" > /dev/null 2> дараа нь echo "hey" , Би "Одоо би аюулгүй болсон!"< <(find "$ dir_work" -type f -print0) while IFS= read -r -d "" f; do echo "2" done < <(find "$dir_work" -type d -name "work" -print0)

дууссан

Таны харж байгаагаар IFS хувьсагч нь хоосон байхаар тохируулагдсан тул унших нь урд болон хойд талын зайг шугамаас таслахаас сэргийлдэг. Унших команд нь хоосон мөрийг (-d "") уншихын тулд a\0 олох хүртэл m байх ёстой тул өгөгдлөө шинэ мөрийн оронд \0-ээр тусгаарлахын тулд -print0 сонголтыг ашигладаг. , гайхалтай бөгөөд хорлонтой нь файлын нэрний нэг хэсэг байж болно. Ийм \n файлыг хоёр хэсэгт хуваах нь бидний кодыг эвдэх болно.

Энэ олдворыг тодорхойлсон өмнөх хариулт... | нэрийг уншиж байх үед; хийх...; хийсэн нь уншихад ашиглагдах ёстой find s гаралт бас муу байж болно. while давталт нь эцэг эхээсээ хуулсан хувьсагчдын өөрийн хуулбартай шинэ дэд бүрхүүлд ажилладаг. Энэ хуулбарыг таны дуртай зүйлд ашиглах болно. while давталт дуусахад дэд бүрхүүлийн хуулбарыг хасч, эх хувьсагчийг өөрчлөхгүй.

0

"Тушаал орлуулалтыг хашилтгүйгээр хэзээ ч бүү ашиглаарай." Энэ бол зүгээр л nitpicking, гэхдээ "something = $(basename" файлын нэр ")" гэсэн хувьсагчийг тохируулахдаа хашилтгүйгээр командын орлуулалтыг ашиглах боломжтой. - Смит ЖонДөрөвдүгээр сарын 22 13 2013-04-22 21:43:10

2

For i in $(хайх$ DIRWORK -type d -name ажил); "2"-г цуурай хийнэ үү

Энэ мөрийг хамгийн түрүүнд гүйцэтгэх болно

$DIRWORK -type d -name ажлыг олоорой

find-г ажиллуулж дуустал хүлээнэ үү, дараа нь нэг өдөр завсарлаад for циклд буцааж оруулна уу

Find-ийн гаралт дахь i-ийн хувьд; "2"-г цуурай хийнэ үү

зөвхөн дараа нь for цикл ажиллаж эхэлнэ.

Хэрэв олох нь for циклийг дуусгахад удаан хугацаа шаардагддаг бол эхлэхээс өмнө удаан хүлээх хэрэгтэй.

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

$ цаг олох $DIRWORK -төрөл d -нэр ажил

мөн хэр удаан үргэлжлэхийг хараарай.

Мөн анхаарна уу: файлын нэрийг давтахдаа for циклийг ашиглах ёсгүй. Уншихтай хамт while давталтыг дараах байдлаар ашиглаарай:

Find$ DIRWORK -төрөл d -нэр ажил | нэрийг уншиж байх үед; "2"-г цуурай хийнэ үү

Бонус: find -тэй зэрэгцэн while циклийг ажиллуулдаг. Энэ нь find нэг мөр хэвлэмэгц while давталт нэг давталт гүйцээнэ гэсэн үг. Гүйцэтгэлийг дуусгахын тулд олохыг хүлээх шаардлагагүй.

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

for гогцоо

Цикл төлөөВ bashхоёр төрөлтэй. Эхлээд сонгодог хувилбарыг харцгаая төлөө. Ерөнхий үзэл бодол нь дараах байдалтай байна.

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

Энд практик жишээ байна:

Утгын дарааллыг янз бүрийн аргаар тодорхойлж болно. Тодорхой байдлаар - дээрх жишээн дээрх шиг, эсвэл бусад хувьсагчийг ашиглах, эсвэл тусгай тушаалуудыг ашиглах. Зарим жишээг харцгаая. Утга нь хоосон зайгаар тусгаарлагдсан байдаг тул эдгээр утгууд нь зай бүхий мөр агуулсан аливаа хувьсагч байж болно.

Үр дүн нь эхний жишээтэй ижил байх болно.

Хэрэв та тоонуудын дарааллыг зааж өгөх шаардлагатай бол командыг ашиглаж болно дараалалболон орлуулах механизм. Баг дараалалтоон утгуудын дарааллыг дэлгэц рүү буцаана. Синтакс нь энгийн бөгөөд доорх жишээнээс тодорхой болно.

Үр дүн:

Хоёрдахь төрөл рүү буцъя төлөө. Ихэнхдээ скриптүүдээс та C-тэй төстэй хувилбарыг олж болно төлөө, энэ нь тоонд суурилсан гогцоонд хэрэглэгддэг. Нэг жишээг харцгаая:

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

Практик жишээ:

#!/bin/bash
i=1
байхад [ $i -lt 7 ]
хийх
echo $i
i=i+1 гэж үзье
хийсэн

Бидний жишээн дээр бид хувьсагч байгаа эсэхийг шалгадаг би(-lt) тоо 7-оос бага бөгөөд хэрэв тийм бол хувьсагчийн утга дэлгэц дээр гарч ирнэ. Илэрхийлэл i=i+1 гэж үзье, хувьсагчийг нэгээр нэмэгдүүлэх, дахин шалгах гэх мэт. let нь аргументуудыг тоон утга гэж хүлээн зөвшөөрөх ёстойг тайлбарлагчид хэлнэ. Энэ мөрийг ингэж бичиж болно би ++ зөвшөөрье(c-тэй төстэй хувилбар). Нэгээс олон тоо нэмэгдэхэд дараах байдлаар бичиж болно. i+=2 гэж үзье- энэ тохиолдолд би 2-ын алхмаар нэмэгдэх болно. Хувьсагчийг нэмэгдүүлэх өөр нэг сонголт бол суурилуулсан тооцоолуур (зөвхөн бүхэл тоогоор ажилладаг) ашиглах явдал юм. Тооцоологч руу давхар хаалтанд хандаж болно: i=$(($i+1))эсвэл квадратаар дамжуулан: i=$[$i+1]Та тушаалын мөрөнд тооцоолуур ашиглаж болно:

Төгсгөлгүй гогцоо үүсгэхгүйн тулд гогцоонд болгоомжтой хандах хэрэгтэй. Дашрамд хэлэхэд дибаг хийх bashскриптүүдийн эхний мөрийг өөрчилж болно #!/bin/bash -xэсвэл скриптийг тушаалаар ажиллуулна уу bash -x:

igor@ubuntu:~/linux$ bash -x ./testfor.sh
+ i=1
+ '[' 1 -gt 5 ']'
+ echo i=1
i=1
+ i=i+1 гэж үзье
+ '[' 2 -gt 5 ']'
+ echo i=2
i=2
+ i=i+1 гэж үзье
+ '[' 3 -gt 5 ']'
+ echo i=3
i=3
+ i=i+1 гэж үзье
+ '[' 4 -gt 5 ']'
+ цуурай i=4
i=4
+ i=i+1 гэж үзье
+ '[' 5 -gt 5 ']'
+ цуурай i=5
i=5
+ i=i+1 гэж үзье
+ '[' 6 -gt 5 ']'

Гогцоонууд хэрхэн ажилладаг талаар ойлголтоо бататгахын тулд жижиг скрипт бичих дадлага хийхээ мартуузай bash.

Bash дахь функцууд

Функцуудыг ашигладаг bashмаш өргөн. Функцуудыг түлхүүр үгээр хоёр янзаар тайлбарладаг функц, мөн түүнгүйгээр.

Эхний арга:

функцийн нэр
{
функциональ бие
}

Хоёр дахь арга:

function_name()
{
функциональ бие
}

Функцийг скриптийн аль ч хэсэгт нэрээр нь дууддаг боловч функцийг өөрөө тайлбарласны дараа л дууддаг. Функцийг мөн функцийн дуудлагын (нэр) дараа хоосон зайгаар тусгаарласан параметрүүдийг дамжуулж болно. Жишээ скриптийг харцгаая bash:

#!/bin/bash
функцын праймер
{
хэрэв [$# -ne 0 ]
тэгээд
орон нутгийн a=1
echo "Өнгөрсөн параметрийн тоо - $#"
миний хувьд $@
хийх
echo "$a-дахь параметр нь $i"
++ өгье
хийсэн
0 буцаана
өөр
echo "Параметрүүдийг дамжуулаагүй"
буцах 1
fi
}
echo "Функцийг параметртэй дуудах:"
праймер a b c
цуурай $?
echo "Параметргүй функцийг дуудах:"
праймер
цуурай $?

Энэ жишээнд функц нэртэй праймер. Параметр бүхий функцийг дуудах: праймер a b cболон параметргүй: праймер. Функцийн үндсэн хэсэгт -аас бусад бүх бүтээц танд танил байх ёстой $# , $iТэгээд $@ .$# — функцэд дамжуулсан параметрийн тоог буцаана. Бидний жишээнд энэ нь тоо байх болно 3 .$@ бүх параметрүүдийг нэг мөрөнд буцаана. Жишээн дээр ийм байх болно a b c. Тэгээд дамжуулан $1 , $2 , $3 гэх мэт. Та параметр бүрт тус тусад нь хандах боломжтой. $? — сүүлийн командын гүйцэтгэх кодыг агуулна. Бидний жишээнд функцийн гүйцэтгэлийн код.

Мөн функц нь түлхүүр үгээр дамжуулан тоон утгыг буцаах боломжтой буцах. Ихэвчлэн функцийг алдаагүй гүйцэтгэсэн тохиолдолд 0 буюу ямар нэг зүйл буруу болвол тэгээс өөр утгыг буцаана. Жишээлбэл, хэрэв функцийг параметрээр дуудсан бол 0 утгыг, хэрэв функцийг параметргүйгээр дуудсан бол 1 кодыг буцаана.

Функцэд параметр дамжуулах бүх зүйл скриптийн хувьд яг адилхан ажилладаг. Та мөн параметрүүдийг скрипт рүү дамжуулж, тэдгээрийг ашиглан ижил аргаар удирдаж болно $#, $@, $N. Үүнтэй ижил ангилалаас сонголт байна - $0 - скриптийг эхлүүлсэн командын нэрийг буцаана. Хэрэв скриптийг тушаалаар ажиллуулсан бол ./script.sh, дараа нь цуурай $0 утгыг буцаана ./script.sh, хэрэв тушаалаар бол /home/igor/linux/script.sh, дараа нь утгыг буцаана /home/igor/linux/script.sh.

© 2024 ermake.ru -- Компьютер засварын тухай - Мэдээллийн портал