Bash Loop - วิธีการหยุดลูปเมื่อฉันกด Control-C ภายในคำสั่ง?


35

ฉันกำลังซิงค์บางไดเรกทอรี ฉันเปิดเทอร์มินัล bash และกำลังใช้งานสิ่งนี้:

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done

อย่างไรก็ตามถ้าฉันต้องการหยุดทุกสิ่งฉันกด Control-C นั่นหยุด rsync แต่จากนั้นมันจะไปต่อที่อื่น ในกรณีนี้ฉันรู้ว่าเกิดอะไรขึ้นและจากนั้นเพียงกด Control-C เหมือนคนบ้าจนทุกอย่างทำงานได้อีกครั้ง

มีวิธีการ 'แก้ไข' นี้ไหม ฉันต้องการมันถ้าฉันมีวงแบบนั้นแล้วกด Control-C เพื่อที่มันจะกลับมาที่เปลือกทุบตีของฉัน


6
เดนนิสคำตอบคือหนึ่งที่เหมาะสม แต่คุณถ้าคุณไม่ได้ทำเช่นนั้นคุณจะได้ไม่ต้อง 'กดมันเหมือนคนบ้า' เพียงแค่ถือมันและปล่อยให้จับแป้นพิมพ์ซ้ำมัน :-)
ไคล์ Brandt

ฉันแค่กด Cntl-C ค้างไว้โดยทั่วไปก็ใช้ได้ดี
Scott Alan Miller

คำตอบ:


33
for DIR in * ; do rsync -a $DIR example.com:somewhere/ || break; done

สิ่งนี้จะออกจากลูปหากการเรียกใช้ rsync แต่ละรายการล้มเหลวด้วยเหตุผลบางประการ


4
เคล็ดลับเพิ่มเติม: หากคุณอยู่ในลูปซ้อนกันและต้องการยุติให้ใช้break 2(หรือแทนที่ "2" ด้วยจำนวนลูปซ้อนที่คุณต้องการยกเลิก)
Dolan Antenucci

26

หากต้องการขยายคำตอบของเดนนิสโค้ดของคุณอาจมีลักษณะดังนี้:

trap "echo Exited!; exit;" SIGINT SIGTERM

สำหรับตัวอย่างการทำงาน (ที่เกิดขึ้นจะเกี่ยวข้องกับ rsync) ตรวจสอบhttp://gist.github.com/279849


ขอบคุณนี้เป็นวิธีการแก้ปัญหาทั่วไปที่ทำงานสำหรับฉัน
wi1

25

คุณสามารถตั้งค่ากับดักสำหรับ Control-C

trap <command> SIGINT

จะดำเนินการcommandเมื่อมีการกด Control-C เพียงแค่วางtrapข้อความในสคริปต์ของคุณ ณ จุดที่คุณต้องการให้มีประสิทธิภาพ


6

เมื่อคุณใส่สตริงคำสั่งไว้ในวงเล็บสตริงจะทำหน้าที่เป็นกระบวนการเดียวและจะได้รับ SIGINT และยุติเมื่อคุณกดCtrl- C:

(for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done)

แต่! ในกรณีของrsyncคำสั่งจะอนุญาตให้มีหลายแหล่งดังนั้นรหัสที่คุณเขียนจะดีกว่าเขียนเป็น:

rsync -a * example.com:somewhere/

6
  1. กดCtrl-Zเพื่อหยุดสคริปต์
  2. kill %%

เครดิตคำอธิบายและรายละเอียดเพิ่มเติมในคำตอบนี้


สิ่งนี้ดีมากเพราะใช้งาน "โพสต์พฤตินัย" เมื่อคุณต้องการที่จะขัดจังหวะลูปที่ใช้งานมานานซึ่งคุณเริ่มแล้ว
Nick Matteo

0

ฉันมักจะใส่คำสั่งอื่นในการวนซ้ำที่สามารถถูกขัดจังหวะได้ง่าย ต้องกด ctrl-C สองอัน

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; sleep 1 ; done

ไม่ใช่โซลูชันที่ยอดเยี่ยมสำหรับ rsync นี้ซึ่งคุณอาจต้องการเรียกใช้อย่างรวดเร็ว แต่มันทำงานได้ดีสำหรับลูปอื่น ๆ เช่นนี้

while true ; do ping -c 10 example.com ; sleep 1 ; done

การวนซ้ำนี้จะค้นหาที่อยู่ของ example.com ทุกครั้งผ่านการวนซ้ำซึ่งมีประโยชน์หากคุณกำลังมองหาการเปลี่ยนแปลง DNS

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