เหตุใดขณะหนึ่งลูปจึงหยุดหลังจากถูกระงับ


10

ทำไมการใช้ bash และหยุดชั่วขณะหนึ่งวงจึงหยุดลงหลังจากกลับมาทำงานต่อ ตัวอย่างสั้น ๆ ด้านล่าง

$ while true; do echo .; sleep 1; done
.
.
^Z
[1]+  Stopped                 sleep 1
$ fg
sleep 1
$

ฉันคุ้นเคยกับสัญญาณและฉันเดาว่านี่อาจเป็นพฤติกรรมตามธรรมชาติของการทุบตีที่นี่ แต่ฉันต้องการที่จะเข้าใจมากขึ้นว่าทำไมมันทำงานในลักษณะนี้โดยเฉพาะ


เพราะมันมีการจัดการกับการขัดจังหวะและมีความแม่นยำในการสะท้อนให้เห็นว่าใน$?การกลับมาและอื่น ๆไม่ได้แล้วtrue trueอาจ. ฉันคิด.
mikeserv

1
ฉันหวังว่าความคิดเห็นนี้จะไม่ถูกตั้งค่าสถานะ แต่ฉันจะตอบคำถามของคุณด้วยคำถามอื่นสไตล์ Unix koan: "ทำไมนักเรียนหยุดต่อสู้บนสนามเด็กเล่นหลังจากเขาถูกระงับ" คำตอบคือเพราะเขาไม่ได้อยู่ที่สนามเด็กเล่นซึ่งเขามีความสามารถในการเริ่มต่อสู้ ดังนั้นพฤติกรรมที่เป็นปัญหาจึงถูกระงับ
rubynorails

คุณหยุดคำสั่งวนซ้ำขาด จากนั้นคุณดำเนินการคำสั่ง sleep 1 เดี่ยวต่อไม่วนซ้ำ
123

คำตอบ:


10

ดูเหมือนว่าข้อผิดพลาดในหลายเปลือกหอยนี้จะทำงานได้ตามที่คาดไว้กับksh93และzsh

พื้นหลัง:

เชลล์ส่วนใหญ่ดูเหมือนจะวิ่งวนรอบในขณะที่เชลล์หลักและ

Bourne Shellระงับทั้งเชลล์หากคุณพิมพ์ ^ Z ด้วยเชลล์ที่ไม่ใช่การล็อกอิน

bash จะหยุดเฉพาะsleepและจากนั้นปล่อยลูป while เพื่อสนับสนุนการพิมพ์ shell prompt ใหม่

เส้นประทำให้คำสั่งนี้ไม่สามารถระงับได้

ด้วยksh93สิ่งต่าง ๆ ทำงานแตกต่างกันมาก:

ksh93ทำเช่นเดียวกันในขณะที่คำสั่งเริ่มต้นเป็นครั้งแรก แต่เป็นsleepbuitin ใน ksh93, ksh93 มีตัวจัดการที่ทำให้ห่วงในขณะที่จะแยกเปลือกหลักแล้วหยุดในเวลาที่คุณพิมพ์ ^ Z

หากคุณอยู่ในksh93ในภายหลังให้พิมพ์fgลูกที่แยกออกซึ่งยังคงเรียกใช้ลูปต่อไป

คุณเห็นความแตกต่างหลักเมื่อเปรียบเทียบข้อความ jobcontrol จาก bash และ ksh93:

รายงานทุบตี :

[1]+ Stopped sleep 1

แต่รายงานksh93 :

^Z[1] + Stopped while true; do echo .; sleep 1; done

zshทำงานคล้ายกับksh93

ด้วยเชลล์ทั้งสองคุณมีกระบวนการเดียว (เชลล์หลัก) ตราบใดที่คุณไม่พิมพ์ ^ Z และสองเชลล์กระบวนการหลังจากคุณพิมพ์ ^ Z


ไม่dashจริงไขลานจัดการสัญญาณเมื่อวงยุติ? ใน[d]?ashรหัสที่มามีทั้งหมดของแมโครเหล่านี้สำหรับINTONและINTOFFแพร่ระบาดไปทั่วและมักจะส่งสัญญาณที่ได้รับในขณะที่ในINTOFFรัฐจริงๆได้รับการจัดการที่(หรือรอบ) INTON อย่างไรก็ตามฉันแค่อยากรู้อยากเห็นเพราะฉันคิดว่าคุณรู้ดีกว่า - เป็นคำตอบที่ดี ขอบคุณ.
mikeserv

ฉันไม่ค่อยใช้เส้นประและเมื่อเร็ว ๆ นี้ฉันดึงข้อมูลและรวบรวมเพื่อเปรียบเทียบประสิทธิภาพกับ bash, ksh93 และ Bourne Shell ของฉัน ขณะทำการทดสอบเหล่านี้ฉันค้นพบว่าเส้นประนั้นส่วนใหญ่ดูเหมือนจะเร็วเพราะไม่รวมการรองรับอักขระหลายไบต์ หนึ่งsleep 100สามารถถูกระงับและดำเนินต่อในdashดังนั้นจึงดูเหมือนว่าdashรู้เกี่ยวกับปัญหาในคำสั่งนี้และเลือกปิดการควบคุมงาน
schily

ดังนั้นในการทดสอบของคุณคุณสามารถที่จะมีdashประสิทธิภาพเท่ากันในเชลล์อื่น ๆ โดยการประมวลผลแบบมัลติไบต์? และใช่dashรองรับการควบคุมงาน แต่มาตรฐานบอกว่าเชลล์แบบโต้ตอบควรละเว้น TSTP และเรียกใช้ห่วงขณะที่ในเชลล์ปัจจุบันที่เทอร์มินัลเชิงโต้ตอบไม่น้อยกว่าเชลล์แบบโต้ตอบใด ๆ
mikeserv

ฉันไม่ได้ทดสอบสิ่งนี้อย่างแน่นอน แต่ฉันเห็นได้ว่าในขณะที่ dash ใช้เวลา CPU ของระบบมากกว่า ksh93 หรือ Bourne Shell (ส่วนใหญ่เป็นเพราะมันมีการเรียก fork () มากขึ้น แต่ใช้เวลา CPU ของผู้ใช้น้อยลง เวลา CPU เทียบกับ Bourne Shell รุ่นของฉัน จากการพยายามลดเวลา CPU ของผู้ใช้ใน Bourne Shell ฉันรู้ว่าส่วนใหญ่เวลานี้ใช้ในการแปลงหลายไบต์
schily

4

ฉันเขียนหนึ่งในผู้เขียนร่วมของ Bash เกี่ยวกับปัญหาและนี่คือคำตอบของเขา:

มันไม่ได้เป็นข้อผิดพลาดจริงๆ แต่มันเป็นข้อแม้อย่างแน่นอน

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

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

ดังนั้นหากใครต้องการส่งแพทช์ให้ใช้ที่อยู่อีเมลที่พบในหน้าคน

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