Bash loop ตั้งแต่ 0 ถึง 100 Bash Basics: ลูป WHILE และ UNTIL วนซ้ำ

วงจร สำหรับแตกต่างจากภาษาโปรแกรมอื่นๆ เล็กน้อย ประการแรก ช่วยให้คุณสามารถดำเนินการตามลำดับกับ "คำ" ในสตริงได้

วงจร ในขณะที่รันโค้ดบางส่วนหากนิพจน์ที่กำลังทดสอบเป็นจริง และหยุดหากเป็นเท็จ (หรือพบการขัดจังหวะลูปที่กำหนดไว้อย่างชัดเจนภายในโค้ดที่รัน)

วงจร จนกระทั่งเกือบจะเหมือนกันกับ while loop ข้อแตกต่างเพียงอย่างเดียวคือโค้ดจะถูกดำเนินการหากนิพจน์ที่กำลังทดสอบเป็นเท็จ

หากคุณคิดว่า while และ until มีความคล้ายคลึงกันมาก แสดงว่าคุณคิดถูก

7.1 ตัวอย่างการวนซ้ำ

#!/bin/bash สำหรับฉันใน $(ls); ทำรายการ echo: $i เสร็จแล้ว

ในบรรทัดที่สอง เราแสดง i เป็นตัวแปรที่ได้รับค่าต่างๆ ที่มีอยู่ใน $(ls)

หากจำเป็น บรรทัดที่สามอาจยาวกว่านี้ หรืออาจมีหลายบรรทัดก่อนทำ (บรรทัดที่ 4)

"done" (บรรทัดที่ 4) บ่งชี้ว่าโค้ดที่ใช้ $i กำลังจะสิ้นสุด และ $i ได้รับค่าใหม่

สคริปต์นี้ไม่ได้ตั้งใจให้มีความสำคัญอย่างยิ่ง แอปพลิเคชั่นที่มีประโยชน์มากขึ้น สำหรับวงจะใช้เพื่อเลือกเฉพาะไฟล์บางไฟล์ในตัวอย่างก่อนหน้า

7.2 C-like สำหรับ

fiesh แนะนำให้เพิ่มแบบฟอร์มลูปนี้ นี่คือ for loop ซึ่งคล้ายกับ for loop มากที่สุดใน C, Perl ฯลฯ

#!/bin/bash สำหรับฉันใน `seq 1 10`;

ทำ echo $i เสร็จแล้ว

7.3 ตัวอย่างขณะวนซ้ำ:

#!/bin/bash COUNTER=0 ในขณะที่ [ $COUNTER -lt 10 ]; ทำเสียงสะท้อน ตัวนับคือ $COUNTER ให้ COUNTER=COUNTER+1 เสร็จสิ้น

สคริปต์นี้ “จำลอง” โครงสร้าง “สำหรับ” ที่รู้จักกันดี (ใน C, Pascal, Perl ฯลฯ) การวนซ้ำเป็นสิ่งที่สะดวกอย่างยิ่งเมื่อเขียนโปรแกรมหรือสคริปต์ใดๆ แม้จะจำเป็นก็ตาม พวกมันอนุญาตให้เรารันโค้ดบางส่วนตามจำนวนครั้งที่ระบุ โดยธรรมชาติแล้ว bash มีลูปหลายประเภท เราจะอธิบายวงจรสำหรับใน, สำหรับ, ในขณะที่, จนกระทั่ง

- แม้ว่า for in และ for จะถือเป็นไวยากรณ์ที่แตกต่างกันของข้อความเดียวกัน แต่ในความคิดของฉัน พวกมันต่างกันมากกว่า while from until:

วงจร ห่วงพร้อมตัวนับสำหรับเข้าสำหรับใน นี่คือการวนซ้ำพร้อมตัวนับ บล็อกของโค้ดที่อยู่ในเนื้อหาของลูปจะถูกทำซ้ำหลาย ๆ ครั้งตามที่มีค่าที่มีอยู่ในรายการสำหรับผู้ปฏิบัติงาน
นอกจากนี้ ในการทำซ้ำแต่ละครั้ง ตัวแปรตัวนับ (ในที่นี้เรียกว่า var แต่แน่นอนว่าคุณสามารถเรียกมันว่าอะไรก็ได้ที่คุณต้องการ) มีค่าขององค์ประกอบถัดไปของรายการ ถ้า do อยู่ในบรรทัดเดียวกับคำว่า for จากนั้นหลังจากรายการอาร์กิวเมนต์ (ก่อนทำ) คุณต้องใส่เครื่องหมายอัฒภาค
แต่ละองค์ประกอบ<список>อาจมีหลายข้อโต้แย้ง สิ่งนี้มีประโยชน์เมื่อประมวลผลกลุ่มของพารามิเตอร์ ในกรณีนี้ เพื่อบังคับให้แยกวิเคราะห์ข้อโต้แย้งแต่ละรายการ<списке>คุณต้องใช้คำสั่งชุด
คุณสามารถใช้ตัวแปรเป็นรายการใน for loop ได้
ใน<списке>for loop สามารถใช้ชื่อไฟล์ ซึ่งในทางกลับกันสามารถมีอักขระไวด์การ์ดได้ สิ่งนี้มีประโยชน์มากเมื่อทำงานกับไฟล์จำนวนมาก
นอกจากนี้ ในการทำซ้ำแต่ละครั้ง ตัวแปรตัวนับ (ในที่นี้เรียกว่า var แต่แน่นอนว่าคุณสามารถเรียกมันว่าอะไรก็ได้ที่คุณต้องการ) มีค่าขององค์ประกอบถัดไปของรายการ<список>ไม่ได้ระบุใน for loop จากนั้นจึงใช้ตัวแปร $@ เป็นรายการอาร์กิวเมนต์บรรทัดคำสั่ง
เมื่อสร้างรายการอาร์กิวเมนต์ คุณสามารถใช้การทดแทนคำสั่งใน for loop ได้
เอาต์พุตของการวนซ้ำสามารถเปลี่ยนเส้นทางจาก stdout ไปยังไฟล์หรือที่อื่นได้ (คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับสิ่งนี้ได้โดยดูที่การเปลี่ยนเส้นทาง I/O)

ไวยากรณ์:
สำหรับ var in<список>
ทำ
<выполняемые команды>
เสร็จแล้ว

ตัวอย่าง:
สำหรับชื่อในชื่อ1 ชื่อ2 ชื่อ3 ชื่อ4
ทำ
สะท้อนชื่อ $
เสร็จแล้ว

ตัวดำเนินการวนซ้ำ สำหรับมีวิธีการเขียนอีกวิธีหนึ่ง - คล้ายกับไวยากรณ์ของตัวดำเนินการ for ในภาษา C ในกรณีนี้เมื่อเริ่มต้นตัวนับจะมีการตั้งค่าเริ่มต้นของตัวแปรหรือตัวแปรหนึ่งตัวและหลังจากผ่านแต่ละลูปเงื่อนไข ถูกเลือก หากเช็คคืนค่าเป็นจริง การวนรอบครั้งถัดไปจะเริ่มต้นขึ้น ในบล็อก<приращение счётчиков>ค่าของตัวนับตัวแปรของเราต้องเปลี่ยนแปลง (ไม่จำเป็นต้องสูงขึ้น) ดังนั้นเมื่อตรวจสอบเงื่อนไข ไม่ช้าก็เร็วเราจะได้ค่าเท็จ ไม่เช่นนั้นการวนซ้ำจะไม่มีวันสิ้นสุด ตัวเลือกที่สะดวกและคุ้นเคยที่สำคัญที่สุดหากจำเป็นต้องทำซ้ำตามจำนวนที่ระบุ

ด้วยไวยากรณ์ที่คล้ายกัน:
สำหรับ ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
ทำ
<выполняемые команды>
เสร็จแล้ว

ตัวอย่าง:
สำหรับ ((var=1; var<= LIMIT ; var++))
ทำ
เสียงสะท้อน $var
เสร็จแล้ว

ในขณะที่วนซ้ำ:

นี่เป็นโครงสร้างที่ค่อนข้างง่ายที่จะตรวจสอบสภาพเบื้องหลังของผู้ปฏิบัติงาน ในขณะที่และหากเงื่อนไขนี้เป็นจริง มันจะดำเนินการบล็อกของคำสั่งที่อยู่ระหว่างคำว่า do และ Done จากนั้นจึงดำเนินการตรวจสอบเงื่อนไขอีกครั้ง หากการตรวจสอบส่งคืนเท็จ รอบจะสิ้นสุดและคำสั่งต่อไปนี้จะเริ่มดำเนินการ: เสร็จแล้ว- จำเป็นอย่างยิ่งที่จะต้องแน่ใจว่า<проверка условия>ขึ้นอยู่กับโค้ดที่ทำงานอยู่ในลูป มิฉะนั้น หากผลลัพธ์ของการตรวจสอบไม่เปลี่ยนแปลง คุณจะได้รับลูปที่ไม่สิ้นสุด
อุปกรณ์อินพุตมาตรฐานสำหรับ ในขณะที่วนซ้ำสามารถเปลี่ยนเส้นทางไปยังไฟล์ได้โดยใช้คำสั่งเปลี่ยนเส้นทาง< в конце цикла.

ไวยากรณ์:
ในขณะที่<Проверка условия>
ทำ
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
เสร็จแล้ว

ตัวอย่าง:
ในขณะที่ [ $var0 -eq 100 ]
ทำ
เสียงสะท้อน $var
วาร์++
เสร็จแล้ว

ผู้ดำเนินการ ในขณะที่อาจมีเงื่อนไขหลายประการ แต่มีเพียงคนสุดท้ายเท่านั้นที่จะกำหนดความเป็นไปได้ในการดำเนินวงจรต่อไป ในกรณีนี้ ไวยากรณ์ของตัวดำเนินการลูปจะแตกต่างจากรูปแบบปกติ
ไวยากรณ์(ฉันขอย้ำอีกครั้งว่าเฉพาะเงื่อนไขสุดท้ายเท่านั้นที่ส่งผลต่อการดำเนินการของลูป) :
ในขณะที่
<условие1>
<условие2>

<условиеN>
ทำ
<выполняемые команды - тело цикла>
เสร็จแล้ว

จนกระทั่งวนซ้ำ:

ผู้ดำเนินการ จนกระทั่งคล้ายกับ while มาก นอกจากนี้ยังประเมินเงื่อนไขด้วย แต่จะประมวลผลเนื้อความของลูปหากผลลัพธ์ของการคำนวณเป็นเท็จ อาจดูผิดปกติ แต่จนกระทั่งประเมินเงื่อนไขก่อนที่จะผ่านครั้งแรกของลูป เช่น ในขณะที่ ไม่ใช่หลังจากนั้น เช่นเดียวกับ for/in loops เมื่อวางคีย์เวิร์ด do ในบรรทัดเดียวกับการประกาศ loop คุณต้องแทรกอักขระ ";" ก่อนทำ
เช่นเดียวกับในกรณีก่อนหน้านี้ สิ่งสำคัญคือต้องจำไว้ว่าเงื่อนไขต้องขึ้นอยู่กับการดำเนินการในเนื้อหาของลูป ไม่เช่นนั้นสคริปต์ของเราจะไม่มีวันเสร็จสมบูรณ์

ไวยากรณ์:
จนกระทั่ง<Проверка условия>
ทำ
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
เสร็จแล้ว

ตัวอย่าง:
จนถึง [ $var0 -gt 100] # มีการตรวจสอบเงื่อนไขเมื่อเริ่มต้นการวนซ้ำ
ทำ
เสียงสะท้อน $var
วาร์--
เสร็จแล้ว

ก็น่าจะเพียงพอแล้วสำหรับตอนนี้ -

  • กลับ
  • ซึ่งไปข้างหน้า

บทความใหม่:

  • การค้นพบเครือข่ายไม่เปิดขึ้นใน Windows 7/8/2008/2012
  • ข้อผิดพลาด: แอปพลิเคชันนี้ไม่สามารถเริ่มทำงานได้เนื่องจากไม่พบหรือโหลดปลั๊กอินแพลตฟอร์ม Qt "windows"
  • การกำหนดค่าการรีสตาร์ทอัตโนมัติของกระบวนการของผู้ปฏิบัติงาน rphost.exe บนเซิร์ฟเวอร์ 1C 8.3
  • วิธีการลดขนาดของบันทึกธุรกรรม (.ldf) ใน MS SQL 2008/20012

    MS SQL เช่นเดียวกับ DBMS อุตสาหกรรมที่ดีอื่นๆ พร้อมด้วยฐานข้อมูล จะเก็บบันทึกธุรกรรมที่ช่วยให้คุณสามารถย้อนกลับสถานะ...

และตอนนี้ก็ถึงหัวข้อที่ห้าของวัฏจักรนี้แล้ว ในนั้นฉันจะดูโครงสร้างการควบคุมของล่ามคำสั่ง bash ต่อไป ในโพสต์ที่แล้ว มีการพูดคุยถึงแถลงการณ์แบบมีเงื่อนไข ตอนนี้ถึงคราวของโครงสร้างภาษาที่สำคัญเช่นตัวดำเนินการแบบวนซ้ำ ลูปก็เหมือนกับเงื่อนไข คือเครื่องมือที่ให้การควบคุมลำดับในการดำเนินการคำสั่ง
Bash รองรับ for, while, until และ select loops ตอนนี้เรามาดูการพิจารณาโดยละเอียดของแต่ละรายการกันดีกว่า

ตัวดำเนินการ for loop

ไวยากรณ์ทั่วไปของคำสั่ง for คือ:

สำหรับตัวแปร
ทำ
รายการคำสั่ง
เสร็จแล้ว

for loop ใน bash แตกต่างอย่างมากจาก for loop ในภาษาโปรแกรมเช่น C หรือ PHP ดังนั้นหากคุณเขียนโปรแกรมด้วยภาษา C คุณจะต้องทำความคุ้นเคยกับความแตกต่างเหล่านี้เพื่อหลีกเลี่ยงความสับสน
จากการทดแทนรูปแบบจะได้รายการคำ ในการวนซ้ำแต่ละครั้ง ตัวแปรจะรับแต่ละค่าที่ตามมาของรายการนี้ และคำสั่งระหว่าง do และ Done จะถูกดำเนินการ การวนซ้ำจะหยุดเมื่อคำในรายการหมด
$ สำหรับวันในวันจันทร์ อังคาร พุธ พฤหัสบดี ศุกร์ สะท้อน “วันนี้เป็น $day” เสร็จแล้ว
คำสงวนของตัวดำเนินการ for สามารถเขียนได้ในบรรทัดเดียว เช่นเดียวกับกรณีในโพสต์ก่อนหน้าสำหรับตัวดำเนินการ if ในการทำเช่นนี้คุณต้องใส่ ";" ลองเขียนตัวอย่างก่อนหน้านี้ใหม่โดยคำนึงถึงความเป็นไปได้นี้:
$ สำหรับวัน ใน จันทร์ อังคาร พุธ พฤหัสบดี ศุกร์; ทำเสียงสะท้อน “วันนี้เป็นวัน $”; เสร็จแล้ว
การไม่มีโครงสร้างเทียบเท่ากับการเขียนด้วย $@ พารามิเตอร์ $@ ถูกกล่าวถึงใน .

ในขณะที่ตัวดำเนินการวนซ้ำ

ไวยากรณ์ทั่วไปของคำสั่ง while คือ:

ในขณะที่รายการ 1
ทำ
รายการ2
เสร็จแล้ว

List1 จะถูกดำเนินการก่อน หากสำเร็จ เช่น ส่งคืนโค้ดศูนย์ การควบคุมจะส่งผ่านไปยัง list2 การวนซ้ำจะดำเนินต่อไปจนกว่าผลลัพธ์ของการดำเนินการ list1 จะไม่เป็นศูนย์ ตัวอย่างเช่น:
i=10 ในขณะที่ [ $i –gt 0 ]; ทำ echo $i i=$(($i-1)) เสร็จแล้ว; สะท้อน "สิ้นสุด"

จนกระทั่งคำสั่งวนซ้ำ

ไวยากรณ์ทั่วไปสำหรับคำสั่งจนกระทั่งคือ:

จนถึงรายการที่ 1
ทำ
รายการ2
เสร็จแล้ว

List1 จะถูกดำเนินการก่อน หากล้มเหลว นั่นคือด้วยโค้ดส่งคืนที่ไม่ใช่ศูนย์ การควบคุมจะส่งผ่านไปยัง list2 การวนซ้ำจะดำเนินต่อไปจนกว่าผลลัพธ์ของการดำเนินการ list1 จะกลายเป็นศูนย์ ตัวอย่างเช่น:
ผม=10 จนถึง [ $i –lt 0 ]; ทำ echo $i i=$(($i-1)) เสร็จแล้ว; สะท้อน "สิ้นสุด"

เลือกคำสั่งวนซ้ำ

ไวยากรณ์ทั่วไปของคำสั่ง select คือ:

เลือกตัวแปร
ทำ
รายการ
เสร็จแล้ว

จากการทดแทนรูปแบบจะได้รายการคำ ผู้ปฏิบัติงานจะเพิ่มหมายเลขลำดับให้กับคำเหล่านี้ และส่งออกทั้งชุดไปยังสตรีมข้อผิดพลาดมาตรฐาน การไม่มีโครงสร้างเทียบเท่ากับการเขียนด้วย $@ หลังจากนั้น ข้อความแจ้งจะปรากฏขึ้นและบรรทัดจะถูกอ่านจากอินพุตมาตรฐาน หากบรรทัดมีตัวเลขที่สอดคล้องกับคำใดๆ จากรายการ ตัวแปรก็จะรับเป็นค่า หากไม่พบคำที่เหมาะสม ค่าของตัวแปรจะกลายเป็นสตริงว่าง หลังจากนี้ รายการคำสั่งจะถูกดำเนินการ และการวนซ้ำจะดำเนินต่อไปจนกว่าจะพบอักขระสิ้นสุดไฟล์ในบรรทัดอินพุต หรือจนกว่าจะพบตัวแบ่งหรือส่งคืนในรายการคำสั่ง
คำสั่งแบ่งและส่งคืนจะควบคุมความคืบหน้าของลูป คำสั่ง break ขัดจังหวะการดำเนินการของลูป ในขณะที่ return ส่งคืนโค้ดผลลัพธ์ (null หรือไม่เป็นศูนย์)
คำสั่ง Select มีประโยชน์สำหรับการสร้างเมนูที่มีลำดับเลข ตัวอย่างเช่น ในไดเร็กทอรี ~/temp มี 3 ไฟล์: proto.txt, file.txt และ readme ตัวอย่างของส่วนของสคริปต์ที่ช่วยให้คุณสามารถดูส่วนใดส่วนหนึ่งของสคริปต์ได้อย่างรวดเร็ว
echo "เลือกไฟล์ที่จะดู:" เลือกไฟล์ใน ~/temp/* Quit; ทำถ้า [ -f $file ]; จากนั้น cat $file; อย่างอื่นพัง; เสร็จแล้ว
โดยการรันสคริปต์นี้ เราจะเห็นบนหน้าจอ:
เลือกไฟล์ที่จะดู:
1) /home/istergul/temp/file.txt
2) /home/istergul/temp/proto.txt
3) /home/istergul/temp/readme.php
4) ลาออก

หัวข้อถัดไปจะดูที่การทดแทนพารามิเตอร์แบบมีเงื่อนไข ฉันหวังว่าจะแสดงความคิดเห็นของคุณ

5

สคริปต์ของคุณถูกเข้ารหัสในลักษณะที่เป็นอันตราย

ก่อนอื่น ฉันสมมติว่าคุณกำลังใช้ Bash เชลล์ เนื่องจากคุณทำเครื่องหมายด้วย "/bash" และ "/for"

ในคำตอบของฉัน ฉันจะอ้างอิงถึงคู่มือ Bash ที่ยอดเยี่ยมนี้ ซึ่งอาจเป็นแหล่งการเรียนรู้ Bash ที่ดีที่สุด

1) ห้ามใช้การทดแทนคำสั่งเพราะว่า หรือชนิดไม่มีเครื่องหมายคำพูด มีปัญหาใหญ่ที่นี่: การใช้ส่วนขยายที่ไม่มีเครื่องหมายคำพูดเพื่อแยกเอาต์พุตออกเป็นอาร์กิวเมนต์

กล่าวโดยเจาะจงคือ $(find$ DIRWORK -type d -name work) และ $(find$ DIR -type f) จะต้องผ่านการแยกคำ ดังนั้นหาก find พบไฟล์ที่มีช่องว่างในชื่อ เช่น "ชื่อไฟล์" ผลลัพธ์ของการแยกคำ Bash จะส่งผ่าน 2 อาร์กิวเมนต์ไปยังคำสั่ง for เพื่อวนซ้ำ นั่นคือหนึ่งรายการสำหรับ "ไฟล์" และอีกรายการหนึ่งสำหรับ "ชื่อ" ในกรณีนี้ คุณคงอยากจะหวังว่าคุณจะได้รับ "ไฟล์: ไม่มีไฟล์หรือไดเร็กทอรีดังกล่าว" และ "ชื่อ: ไม่มีไฟล์หรือไดเร็กทอรีดังกล่าว" แทนที่จะสร้างความเสียหายให้กับสิ่งเหล่านั้นหากมีอยู่จริง

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; ทำ # ฉันเดาว่าคุณต้องการละเว้น stderr; # นี่คือที่มาของ 2>&1 ถ้า lsof -n " ​​​​$f" | grep "" > /dev/null 2> จากนั้นก้อง "เฮ้ , ฉัน "ฉันปลอดภัยแล้ว!"< <(find "$ dir_work" -type f -print0) while IFS= read -r -d "" f; do echo "2" done < <(find "$dir_work" -type d -name "work" -print0)

เสร็จแล้ว

คำตอบก่อนหน้าซึ่งระบุว่า find... | ขณะอ่านชื่อ ทำ...; เสร็จแล้วควรใช้ในการอ่าน find ผลลัพธ์ก็อาจไม่ดีเช่นกัน while วนซ้ำทำงานในเชลล์ย่อยใหม่โดยมีสำเนาของตัวแปรที่คัดลอกมาจากพาเรนต์ของตัวเอง สำเนานี้จะใช้สำหรับสิ่งที่คุณต้องการ เมื่อการวนซ้ำ while เสร็จสิ้น สำเนาเชลล์ย่อยจะถูกยกเลิก และตัวแปรดั้งเดิมของพาเรนต์จะไม่ได้รับการแก้ไข

หากคุณตั้งใจที่จะเปลี่ยนตัวแปรบางตัวภายใน while loop นี้และใช้ตัวแปรเหล่านั้นในภายหลังในพาเรนต์ ให้พิจารณาใช้สคริปต์ที่ปลอดภัยยิ่งขึ้นซึ่งจะป้องกันข้อมูลสูญหาย

0

"ห้ามใช้การทดแทนคำสั่งทุกชนิด โดยไม่มีเครื่องหมายคำพูด" นี่เป็นเพียง nitpicking แต่เป็นไปได้ที่จะใช้การทดแทนคำสั่งโดยไม่ต้องใส่เครื่องหมายคำพูดเมื่อคุณตั้งค่าตัวแปร: "something = $(basename" filename with spaces ")" - สมิธ จอห์น 22 เม.ย 13 2013-04-22 21:43:10

2

สำหรับฉันใน $(find$ DIRWORK -type d -name work); ทำ echo "2" เสร็จแล้ว

จะเป็นคนแรกที่ดำเนินการบรรทัดนี้

ค้นหา $DIRWORK -type d -name work

รอจนกว่า find จะดำเนินการเสร็จสิ้น จากนั้นจึงหยุดงานหนึ่งวันแล้วนำกลับเข้าสู่ for loop

สำหรับฉันในผลลัพธ์ของการค้นหา; ทำ echo "2" เสร็จแล้ว

จากนั้น for loop จะเริ่มดำเนินการ

ดังนั้นหากการค้นหาใช้เวลานานในการสิ้นสุด for loop ก็ต้องรอเป็นเวลานานก่อนที่จะสามารถเริ่มต้นได้

ลองคำสั่งค้นหาชั่วคราวแบบโต้ตอบ

$ time ค้นหา $DIRWORK -type d -name work

และดูว่าต้องใช้เวลานานเท่าใด

หมายเหตุด้วย: คุณไม่ควรใช้ for loop เพื่อวนซ้ำชื่อไฟล์ ใช้ while วนซ้ำเพื่ออ่านดังนี้:

ค้นหา $ DIRWORK -type d -name work | ขณะอ่านชื่อ ทำ echo "2" เสร็จแล้ว

โบนัส: มันรัน while loop ขนานกับ find ซึ่งหมายความว่าการวนซ้ำ while จะวนซ้ำหนึ่งครั้งทันทีที่พบว่ามีบรรทัดเดียว ไม่จำเป็นต้องรอให้การค้นหาดำเนินการให้เสร็จสิ้น

กฎพื้นฐานประการหนึ่งของการบริหารระบบสามารถแสดงได้ดังนี้: หากคุณต้องการทำสิ่งเดียวกันบ่อยๆ ให้เขียนสคริปต์และปล่อยให้มันทำงานแทนคุณ หากคุณต้องการดำเนินการบางอย่างภายในสคริปต์หลายครั้ง คุณควรใช้ รอบ- ใน GNU ทุบตีคุณสามารถสร้างลูปโดยใช้โครงสร้าง สำหรับ, ในขณะที่และ จนกระทั่ง.

หากคุณเคยสนใจการเขียนโปรแกรม เป็นไปได้มากว่าคุณจะคุ้นเคยกับโครงสร้างเหล่านี้อยู่แล้ว ถ้าอย่างฉันคุณกำลังเรียนอยู่ ทุบตีหากไม่มีประสบการณ์ด้านการเขียนโปรแกรม การใช้ลูปอาจไม่ชัดเจนพอที่จะเข้าใจ เริ่มต้นด้วยการกำหนดความแตกต่างระหว่างลูปประเภทต่างๆ จากนั้นไปยังตัวอย่าง

วงจร สำหรับได้รับการออกแบบมาเพื่อทำซ้ำการกระทำจนกว่าจะเสร็จสิ้นทั้งหมด ลองนึกภาพว่าคุณมีแคตตาล็อกรูปภาพและคุณจำเป็นต้องแปลงรูปภาพจากรูปแบบหนึ่งไปเป็นอีกรูปแบบหนึ่ง คุณสามารถใช้การวนซ้ำ สำหรับร่วมกับโปรแกรม แปลงจากแพ็คเกจ ImageMagick(หรือโปรแกรมอื่นๆ) เช่น เพื่อแปลงรูปภาพจากรูปแบบ JPEG เป็นรูปแบบ PNG หรือตัวอย่างเช่น คุณอาจต้องแปลงไฟล์เสียงจำนวนมากจาก เอ็มพี3วี โอจีจี วอร์บิส.

วงจร ในขณะที่ใช้ในการทำซ้ำการกระทำ ลาก่อนถูกดำเนินการ (คือ จริง) เงื่อนไขบางอย่าง วงจร จนกระทั่งทำงานแตกต่างออกไปเล็กน้อย: ดำเนินการ จนกระทั่งถึงตอนนั้นจนกว่าจะตรงตามเงื่อนไข ตัวอย่างเช่น คุณสามารถมีตัวนับและดำเนินการได้ จนกระทั่งถึงตอนนั้นจนกระทั่งค่าถึง 10 ลองดูรายละเอียดเพิ่มเติมโดยใช้ตัวอย่าง

เริ่มจากวงจรกันก่อน สำหรับ- รูปแบบคือ:

สำหรับฉันอยู่ใน $(command); ทำคำสั่ง $i; เสร็จแล้ว

หากคุณกำลังใช้การวนซ้ำ สำหรับในสคริปต์ควรจัดรูปแบบดังนี้:

#!/bin/bash สำหรับฉันใน $(คำสั่ง); ทำคำสั่ง $i เสร็จแล้ว

ตัวอย่างเช่น หากคุณต้องการสร้างสำเนาสำรองของไฟล์ HTML ทั้งหมดที่อยู่ในไดเร็กทอรี คุณสามารถใช้คำสั่งต่อไปนี้:

สำหรับฉันใน $(ls *html); ทำ cp $i $i.bak; เสร็จแล้ว

มีการสร้างตัวแปรท้องถิ่นที่นี่ $ฉันคำสั่งจะถูกดำเนินการ ls *htmlผลลัพธ์ที่ได้จะเป็นข้อมูลที่เริ่มต้นค่าของตัวแปร $ฉันในการวนซ้ำแต่ละครั้ง (ในตัวอย่างของเรา นี่จะเป็นรายการไฟล์ที่ส่งคืนโดยคำสั่ง LSหนึ่งรายการสำหรับการวนซ้ำแต่ละครั้ง) จากนั้นคำสั่งจะถูกดำเนินการ ซีพีซึ่งตัวแปรจะถูกส่งผ่านไปยังพารามิเตอร์ต่างๆ $ฉัน.

บางคนอาจถามว่าจำเป็นต้องใช้จดหมายหรือไม่ "ฉัน"เป็นชื่อตัวแปร? เลขที่ คุณสามารถใช้สิ่งที่ถูกต้องได้ ทุบตีชื่อตัวแปร แน่นอนว่า ควรใช้ชื่อตัวแปรที่มีความหมายมากกว่าในสคริปต์ของคุณ เช่น $อินพุตหรือ $html.

ฉันยกตัวอย่างการใช้ลูปที่สั้นและเรียบง่าย สำหรับ- แทนที่จะเป็นคำสั่งที่ดำเนินการในบล็อก ทำ,ใช้ เสียงสะท้อนเพื่อดูพารามิเตอร์ที่ส่งไป นี่เป็นแนวทางปฏิบัติที่มีประโยชน์มากในระหว่างขั้นตอนการทดสอบสคริปต์ และยังเป็นวิธีที่ดีในการช่วยให้คุณเข้าใจงานโดยละเอียดมากขึ้นอีกด้วย สำหรับ.

ในขณะที่และจนกระทั่ง

ให้เราพิจารณาการก่อสร้าง ในขณะที่และ จนกระทั่ง- นอกจากนี้เรายังจะใช้เงื่อนไข bash เล็กน้อย ในตัวอย่างของเรา เราจะใช้ตัวแปรเหล่านี้เพื่อกำหนด เช่น ค่าของตัวแปรมากกว่าหรือน้อยกว่าตัวเลข X ไฟล์มีอยู่และเป็นไดเร็กทอรีหรือไม่ คุณยังสามารถใช้นิพจน์แบบมีเงื่อนไขเพื่อพิจารณาว่าไฟล์นั้นสามารถอ่านได้หรือไม่ หรือไฟล์นั้นมีบิต GID อยู่ในสิทธิ์อนุญาตหรือไม่

มาลองทำสิ่งง่ายๆ เช่น การสร้างไฟล์เปล่าๆ สิ่งนี้ไม่น่าจะเป็นประโยชน์กับคุณในชีวิต แต่เป็นตัวอย่าง นี่คือสิ่งนี้

#!/bin/bash i=0 ในขณะที่ [ $i -lt 22 ] แตะที่ $i i=$[$i+1] เสร็จแล้ว

สคริปต์นี้จะสร้างไฟล์ 22 ไฟล์ที่มีชื่อตั้งแต่ 0 ถึง 21 การวนซ้ำจะทำงานจนถึง ลาก่อนค่าตัวแปร $ฉันน้อย ( -lt) 22.

ตอนนี้เรามากำจัดไฟล์ที่สร้างขึ้นโดยใช้การวนซ้ำ จนกระทั่ง:

#!/bin/bash i=0 จนถึง [ $i -eq 22 ] do rm $i i=$[$i+1] เสร็จแล้ว

ที่นี่เราได้แทนที่ ในขณะที่บน จนกระทั่งและในนิพจน์เงื่อนไขที่พวกเขาแทนที่ "น้อย" (-lt) บน "เท่ากับ" (-eq- ดังนั้นสคริปต์ของเราจะทำงานตราบเท่าที่ค่านั้น $ฉันจะไม่ถึง 22. และแทน สัมผัสเราใช้ RMเพื่อลบไฟล์แทนที่จะสร้างมันขึ้นมา ง่ายใช่มั้ย?



2024 wisemotors.ru. วิธีนี้ทำงานอย่างไร. เหล็ก. การทำเหมืองแร่ สกุลเงินดิจิทัล