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


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.