วิธีการทำ ctrl + c / not / ขัดจังหวะ while-loop?


11

รับห่วงนี้:

while sleep 10s ; do
  something-that-runs-forever
done

เมื่อฉันกด Ctrl + C ทั้งวงในขณะที่วงถูกขัดจังหวะ สิ่งที่ฉันต้องการจะทำคือการขัดจังหวะ "บางสิ่งบางอย่าง" - ประมวลผลให้ผ่านไป 10 วินาทีแล้วเริ่ม "บางอย่าง" ใหม่

ฉันจะทำให้ ctrl + c ส่งผลกระทบกับ "บางอย่าง" เท่านั้นและไม่ใช่ while-loop ได้อย่างไร

แก้ไข: "ขัดจังหวะ" เช่นเดียวกับใน SIGINT ฆ่า. ยกเลิก ยุติ ไม่ "ขัดจังหวะ" ในขณะที่ "หยุด"


หากคุณเพียงแค่ต้องการที่จะหยุดมันทำไมไม่ใช้ Ctrl + Z, รอ 10 วินาทีและเรียกใช้fg? ทำไมต้องใช้ Ctrl + C เลย
terdon

@terdon: ขอบคุณสำหรับความคิดเห็นฉันอาจรีบไปพร้อมกับคำตอบ จำเป็นต้องอ่านเพิ่มเติมเกี่ยวกับข้อกำหนดของ OP
Inian

@terdon: ฉันไม่ต้องการหยุดมันชั่วคราว ฉันต้องการผ่านไป 10 วินาทีเหมือนที่ฉันเขียน
bos

What I want to do is to interrupt the "something"-process, let 10 seconds pass, and then restart "something"คุณบอกว่า: หากคุณกด Ctrl + Z รอ 10 วินาทีจากนั้นเรียกใช้fgนั่นคือสิ่งที่จะเกิดขึ้น บางทีคุณสามารถแก้ไขคำถามของคุณและให้ตัวอย่างที่เฉพาะเจาะจงเพื่อให้เราเข้าใจได้ดีขึ้น
terdon

3
ฉันคิดว่าในบริบทของการขัดจังหวะ Ctrl + C นั้นไม่คลุมเครือ แต่เห็นได้ชัดว่าฉันผิด ตอนนี้ฉันแก้ไขแล้ว
bos

คำตอบ:


18

มันควรจะทำงานถ้าคุณtrap SIGINTต้องการอะไรซักอย่าง กดไลค์:( true)

#!/bin/sh
trap ":" INT    
while sleep 10s ; do
    something-that-runs-forever
done

การขัดจังหวะการsomething...ไม่ทำให้เชลล์ออกจากตอนนี้เนื่องจากมันไม่สนใจสัญญาณ อย่างไรก็ตามถ้าคุณ ^ C sleepกระบวนการมันจะจบการทำงานด้วยความล้มเหลวและลูปจะหยุดเนื่องจาก ย้ายsleepไปที่ด้านในของลูปหรือเพิ่มสิ่งที่ต้องการ|| trueเพื่อป้องกัน

หมายเหตุว่าถ้าคุณใช้trap "" INTจะไม่สนใจสัญญาณสมบูรณ์ (แทนการกำหนดคำสั่งกับมัน) ก็ยังไม่สนใจในกระบวนการเด็กดังนั้นแล้วคุณไม่สามารถขัดจังหวะsomething...อย่างใดอย่างหนึ่ง สิ่งนี้ถูกกล่าวถึงอย่างชัดเจนในคู่มืออย่างน้อยของ Bash :

หากargเป็นสตริงว่างดังนั้นสัญญาณที่ระบุโดยแต่ละsigspecจะถูกละเว้นโดยเชลล์และคำสั่งที่เรียกใช้ [... ] สัญญาณที่ถูกละเว้นเมื่อเข้าสู่เชลล์ไม่สามารถดักจับหรือรีเซ็ตได้


สามารถทำได้ในเชลล์ปัจจุบันหรือไม่? (ไม่ใช่ในสคริปต์)

1
คุณอาจต้องการdo (trap - INT; something-that-runs-forever)อนุญาตการขัดจังหวะของคำสั่ง นอกจากนี้คุณไม่จำเป็นต้องเรียกใช้:- trap '' INTคุณก็สามารถใช้เป็นสตริงว่างที่จะไม่สนใจสัญญาณ: ทั้งหมดนี้คือ POSIX และควรทำงานกับเชลล์ที่เข้ากันได้ (ไม่ใช่แค่ Bash)
Toby Speight

ยังทราบว่าการเขียนSIGINTในเต็มรูปแบบไม่เคร่งครัดแบบพกพา: " การใช้งานอาจอนุญาตให้ชื่อกับSIGคำนำหน้าหรือละเว้นกรณีในชื่อสัญญาณเป็นส่วนขยาย . (เน้นของฉัน)"
Toby Speight

คุณสามารถส่งสตริงว่างเป็นการดำเนินการเพื่อละเว้นสัญญาณเช่นtrap "" INT( เช่นposix)
daf

@TobySpeight เหตุผลที่ฉันใช้trap :แทนที่จะtrap ""เป็นอย่างนั้นคือไม่มีสัญญาณที่ถูกเพิกเฉย (แต่ทำให้มันเป็นแบบไม่มี op แทน) ดังนั้นเราจึงไม่จำเป็นต้องทำสิ่งใดเพื่อขัดขวางsomethingโปรแกรมหลัก
ilkkachu

0

อีกทางเลือกหนึ่งคือการsomething-that-runs-foreverจัดการสัญญาณ (ออกอย่างงดงามเมื่อได้รับ) แน่นอนว่ามันสมเหตุสมผลที่จะทำเมื่อโปรแกรมนี้ถูกใช้ในสคริปต์จำนวนมากและพฤติกรรมที่ต้องการในCTRL+ Cจะเป็นระบบเดียวกัน - เพื่อดำเนินการสคริปต์ต่อไป


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