รันคำสั่งเชลล์ซ้ำ ๆ จนกว่าจะล้มเหลว?


191

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

ฉันได้ตั้งค่าการทดสอบเพื่อให้สามารถใช้งานได้โดย:

./runtest

ทางออกปัจจุบันของฉันคือการเขียนuntilfailสคริปต์:

#!/bin/bash
$@
while [ $? -eq 0 ]; do
    $@
done

จากนั้นใช้:

untilfail ./runtest

มีวิธีแก้ไขที่ง่ายกว่านี้ไหม?


11
หมายเหตุด้านข้าง: อ้างเป็นประจำ "$ @"
jordanm

คำตอบ:


327

while ใช้คำสั่งเพื่อดำเนินการเพื่อให้คุณสามารถใช้ง่ายขึ้น

while ./runtest; do :; done

สิ่งนี้จะหยุดลูปเมื่อ./runtestส่งคืนโค้ดการออกที่ไม่ใช่ศูนย์ (ซึ่งโดยปกติจะบ่งบอกถึงความล้มเหลว)

เพื่อให้การแก้ปัญหาปัจจุบันของคุณง่ายขึ้นคุณควรเปลี่ยนสคริปต์จนกระทั่งของคุณเป็นดังนี้:

#!/bin/bash

while "$@"; do :; done

จากนั้นคุณสามารถเรียกมันด้วยคำสั่งที่คุณใช้อยู่:

untilfail ./runTest --and val1,val2 -o option1 "argument two"

25
เป็นการดีที่จะชี้ให้เห็นว่า[เป็นคำสั่ง เป็นการเข้าใจผิดทั่วไปกับผู้ใช้ใหม่ที่[เป็นส่วนหนึ่งifและwhileไวยากรณ์
jordanm

2
ฉันจะนับจำนวนครั้งที่มันวิ่งก่อนที่มันจะล้มเหลวได้อย่างไร
GrantJ

13
@ GrantJ: จริงๆแล้วมันง่ายจริงๆ ใส่count=0ก่อนหน้าวนซ้ำจากนั้นแทน:การวนซ้ำ (ไม่มีตัวเลือก) ใส่(( count++ ))- สิ่งนี้จะเพิ่มตัวนับ
nneonneo

14
แฮ็คผลผลิต: หากคุณอยู่ในระบบด้วยsayและลำโพงคุณสามารถใช้while ./runtest; do :; done && say test failedเพื่อรับการแจ้งเตือนถ้ามันหยุด
Schneems

5
@Schneems: น่าสังเกตว่าsayเป็น macOS-specific
nneonneo

13

หากคุณไม่ต้องการตัดบรรทัดไปป์ที่ซับซ้อนลงในเชลล์สคริปต์หรือฟังก์ชั่นการทำงานก็จะได้ผลดังนี้:

while true; do 
  curl -s "https:..." | grep "HasErrors.:true"
  if [[ "$?" -ne 0 ]]; then 
    break
  fi
  sleep 120
done

คำร้องขอ HTTP ในกรณีนี้ส่งคืน 200 เสมอ แต่จะส่งคืน JSON บางส่วนที่มีแอตทริบิวต์ "HasErrors": จริงเมื่อมีข้อผิดพลาด


1

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

retry --until=fail ./runtest

ตัวอย่างที่ซับซ้อนมากขึ้น:

retry --until=fail --message="test succeeded" --delay=1 ./runtest

เครื่องมือที่มีอยู่จากhttps://github.com/minfrin/retry

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