ทำ ... ในขณะที่หรือทำ ... จนกระทั่งในสคริปต์เชลล์ POSIX


16

มีwhile condition; do ...; doneลูปที่รู้จักกันดีแต่มีdo... whileลูปสไตล์ที่รับประกันการดำเนินการบล็อกอย่างน้อยหนึ่งรายการหรือไม่


ขอบคุณมาก Shawn ฉันไม่ได้คาดหวังว่าคำตอบจะกลายเป็นคำตอบที่เลือกอย่างรวดเร็ว ดังนั้น: ขอบคุณสำหรับการเลือก

คำตอบ:


15

เวอร์ชั่นอเนกประสงค์ที่do ... whileมีโครงสร้างนี้:

while 
      Commands ...
do :; done

ตัวอย่างคือ:

#i=16
while
      echo "this command is executed at least once $i"
      : ${start=$i}              # capture the starting value of i
      # some other commands      # needed for the loop
      (( ++i < 20 ))             # Place the loop ending test here.
do :; done
echo "Final value of $i///$start"
echo "The loop was executed $(( i - start )) times "

เนื่องจากเป็น (ไม่ได้ตั้งค่าไว้i) ลูปจะดำเนินการ 20 ครั้ง
ยกเลิกการแสดงความคิดเห็นบรรทัดที่ตั้งค่าiเป็น 16 i=16, ลูปจะดำเนินการ 4 ครั้ง
สำหรับi=16, i=17, และi=18i=19

หากฉันถูกตั้งค่าเป็น (สมมติว่า 26) ที่จุดเดียวกัน (เริ่มต้น) คำสั่งจะยังคงถูกเรียกใช้งานในครั้งแรก (จนกว่าคำสั่งวนรอบจะถูกทดสอบ)

การทดสอบในขณะที่ควรเป็นจริง (สถานะออกจาก 0)
การทดสอบควรย้อนกลับสำหรับลูปจนกว่าจะกล่าวถึง: เป็นเท็จ (สถานะออกไม่ใช่ 0)

POSIX เวอร์ชันต้องการเปลี่ยนแปลงองค์ประกอบหลายอย่างเพื่อให้ทำงาน:

i=16
while
       echo "this command is executed at least once $i"
       : ${start=$i}              # capture the starting value of i
       # some other commands      # needed for the loop
       i="$((i+1))"               # increment the variable of the loop.
       [ "$i" -lt 20 ]            # test the limit of the loop.
do :;  done
echo "Final value of $i///$start"
echo "The loop was executed $(( i - start )) times "

./script.sh
this command is executed at least once 16
this command is executed at least once 17
this command is executed at least once 18
this command is executed at least once 19
Final value of 20///16
The loop was executed 4 times 

โปรดทราบว่าหากคุณใช้set -eสิ่งใดที่ล้มเหลวในบล็อกเงื่อนไขแบบมีเงื่อนไขจะไม่หยุดการทำงาน: เช่นset -e; while nonexistentcmd; true; do echo "SHiiiiit"; exit 3; done-> อึเกิดขึ้น ดังนั้นหากคุณใช้สิ่งนี้คุณจะต้องระมัดระวังในการจัดการข้อผิดพลาดเช่นเชนคำสั่งทั้งหมดด้วย&&!
Timo

17

ไม่มีการทำ ... ในขณะที่หรือทำ ... จนกว่าจะวน แต่สิ่งเดียวกันสามารถทำได้เช่นนี้:

while true; do
  ...
  condition || break
done

สำหรับจนกว่า:

until false; do
  ...
  condition && break
done

คุณสามารถใช้เส้นแบ่งอย่างใดอย่างหนึ่งกับห่วงอย่างใดอย่างหนึ่ง - ในขณะที่จริงหรือจนกว่าเท็จเพียงหมายถึง 'ตลอดไป' ฉันเข้าใจว่ามันคงสภาพขณะ - หรือ - จนกว่า - จะมีสภาพความสุข - ทางออกหรือเศร้า - ทางออก
android.weasel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.