วัตถุประสงค์ของการระงับที่ล่าช้า (Ctrl-Y) ใน Bash คืออะไร?


30

ส่วนเต็มของหน้า Bash man ซึ่งมีผลบังคับใช้จะบอกว่า:

หากระบบปฏิบัติการที่ใช้ bash รองรับการควบคุมงาน bash จะมีระบบอำนวยความสะดวกในการใช้งาน การพิมพ์อักขระ suspend (โดยทั่วไปคือ ^ Z, Control-Z) ในขณะที่กระบวนการกำลังทำงานอยู่ทำให้กระบวนการนั้นหยุดลงและส่งกลับการควบคุมไปยัง bash การพิมพ์อักขระหยุดทำงานล่าช้า (โดยทั่วไปคือ ^ Y, Control-Y) ทำให้กระบวนการหยุดทำงานเมื่อพยายามอ่านอินพุตจากเทอร์มินัลและการควบคุมจะถูกส่งกลับไปยังทุบตี ผู้ใช้อาจจัดการกับสถานะของงานนี้โดยใช้bg คำสั่งเพื่อดำเนินการต่อในพื้นหลังfgคำสั่งเพื่อดำเนินการต่อในเบื้องหน้าหรือคำสั่ง kill เพื่อฆ่ามัน A ^ Z มีผลบังคับใช้ทันทีและมีผลข้างเคียงเพิ่มเติมที่ทำให้การส่งออกและประเภทหัวพิมพ์ที่รอดำเนินการถูกยกเลิก

ฉันไม่เคยใช้Ctrl- Y; ฉันเพิ่งเรียนรู้เกี่ยวกับมัน ฉันทำได้ดีกับCtrl- Z(ระงับ) เท่านั้น

ฉันพยายามจินตนาการว่าตัวเลือกนี้มีไว้เพื่ออะไร มันจะมีประโยชน์เมื่อไหร่?

(โปรดทราบว่าคุณลักษณะนี้ไม่มีอยู่ในรุ่น Unix ทั้งหมดมีอยู่ในSolarisและFreeBSDแต่ไม่ใช่ใน Linux การตั้งค่าที่สอดคล้องกันคือstty dsusp)

บางทีอาจจะน้อยจิตใจ: มีอะไรที่สามารถทำได้ด้วยCtrl- Yที่ไม่สามารถทำได้อย่างง่ายดายเพียงแค่มีCtrl- Z?


@Gilles แม้ว่า FreeBSD ดูเหมือนว่าจะเป็นstty dsuspฉันไม่ได้จัดการให้ส่ง SIGTSTP เมื่อ ^ Y (ฉันใช้กับ Solaris) มีไหม
Stéphane Chazelas

คำตอบ:


23

จากคู่มือ 4BSD สำหรับ csh :

A ^Zจะมีผลทันทีและเป็นเหมือนการขัดจังหวะในเอาต์พุตที่ค้างอยู่และอินพุตที่ยังไม่ได้อ่านจะถูกยกเลิกเมื่อพิมพ์ มีคีย์พิเศษอื่น^Yที่ไม่สร้างสัญญาณ STOP จนกว่าโปรแกรมจะพยายามอ่าน (2) สิ่งนี้สามารถพิมพ์ได้อย่างมีประโยชน์ก่อนเมื่อคุณเตรียมคำสั่งบางอย่างสำหรับงานที่คุณต้องการหยุดหลังจากที่ได้อ่าน

ดังนั้นวัตถุประสงค์คือเพื่อพิมพ์อินพุตหลายอินพุตขณะที่กำลังประมวลผลแรกและหยุดการทำงานหลังจากที่เสร็จสิ้น


คำอธิบายนี้แตกต่างจากคู่มือทุบตีอย่างละเอียด "... ไม่ก่อให้สัญญาณหยุดจนกว่าความพยายามโปรแกรมที่จะอ่านมัน. " เสียงมันเหมือนทุกอย่างในการป้อนข้อมูลสตรีมถึง^Yจะอ่านประสบความสำเร็จและจากนั้นเมื่อ^Yถูกตีการที่จะหยุด ฉันอ่านถูกไหม
Wildcard

@Wildcard ในการทดสอบของฉันบน Mac OS X กระบวนการจะหยุดก่อนที่จะอ่าน () ส่งคืน (แต่หลังจากการเรียกเพื่ออ่าน () ที่จะกลับมาทำงาน Y) และหลังจากที่มันกลับมาทำงานต่อได้รับอินพุตจากก่อน ^ Y . ฉันคิดว่านี่เป็นจุดประสงค์ที่จะใช้แม้ว่ามันจะถูกใช้ในช่วงเริ่มต้นของบรรทัดดังนั้นพฤติกรรมในกรณีนี้จะไม่สำคัญ ฉันสงสัยว่าในรหัสจริงมันจะถูกระงับเมื่อ ^ Y จะถูกคัดลอกไปยังบัฟเฟอร์การอ่านกระบวนการของผู้ใช้
Random832

ฉันพูดถูกในฟังก์ชั่น ttread ของเคอร์เนล BSD ดั้งเดิมคุณสามารถเห็นสิ่งนี้และOSX ที่ทันสมัย
Random832

แต่เมื่อกระบวนการทำงานต่อการโทรจะสำเร็จและจะมีข้อมูลที่คุณพิมพ์ลงในเทอร์มินัลของคุณก่อน^Yแม้ว่าคุณจะปฏิเสธกระบวนการและปิดเทอร์มินัลของคุณก่อนที่กระบวนการจะกลับมาทำงานต่อ ขวา? ( "... หลังจากที่กลับมาทำงานอีกครั้งจะได้รับอินพุตจากก่อน ^ Y" นั่นคือสิ่งที่ฉันหมายถึงฉันมักจะไม่จัดการในรหัส C) :)
Wildcard

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

11

สมมติว่ามีอินพุตการอ่านลูปและดำเนินการ อาจเป็นประโยชน์ในการปล่อยให้งานเสร็จสิ้นคำสั่งปัจจุบันที่คำนวณโดยไม่ขัดจังหวะก่อนที่จะกลับไปที่บรรทัดคำสั่งสำหรับงานใหม่ ดังนั้นจะจบรอบ สิ่งนี้จะสิ้นสุดลูปอย่างนุ่มนวลและป้องกันไม่ให้มันทำงานอีกครั้งหากreadอยู่ภายใต้ข้อ จำกัด การหมดเวลา


แต่ถ้ามันจะพยายามที่จะอ่านข้อมูลจากสถานีอยู่แล้วก็จะหยุดที่จุดนั้น (และรอสำหรับการป้อนข้อมูลของคุณ) และคุณสามารถ^Zมันแล้ว
Wildcard

ใช่. ดูการอัพเดต
โทมัส

ตรวจสอบอีกหนึ่งรายการ @Wildcard
Tomasz

1
แต่ถ้ามันหมดเวลาแล้วมันจะจบอย่างสง่างามหรือเปล่าถ้าคุณไม่ทำอะไรเป็นพิเศษ?
Daniel Wagner

1
มันอาจจะ. แต่มันอาจจะทำงานต่อไปและเริ่มต้นทำงานบางอย่าง
Tomasz

4

ฉันสามารถนึกถึงสถานการณ์หนึ่งที่อาจมีประโยชน์ แต่เป็นกรณีขอบที่วางแผนไว้

สมมติว่าคุณกำลังดีบักสคริปต์ที่เขียนไฟล์ชั่วคราวที่คุณต้องการวิเคราะห์ก่อนที่จะถูกลบออกเป็นส่วนหนึ่งของรูทีนการล้างข้อมูล

คุณสามารถเพิ่มread fooที่ไหนสักแห่งหลังจากเขียนไฟล์ (แต่ก่อนการล้างข้อมูล) ให้เรียกใช้สคริปต์และกดCtrl- Yเมื่อไฟล์ถูกสร้างขึ้น จากนั้นคุณจะถูกนำไปที่พรอมต์ด้วยสคริปต์ที่ถูกระงับในพื้นหลังเพื่อทำสิ่งที่คุณต้องทำและจากนั้นfgจะอนุญาตให้สคริปต์ดำเนินการให้เสร็จสมบูรณ์


1
ดูเหมือนไม่น่าจะเป็นเพราะสคริปต์จะรออินพุตอยู่ดี ^Zเพื่อให้คุณได้อย่างง่ายดายเพียงแค่ดูให้มันให้คุณเข้าแล้วระงับด้วย ในคำอื่น ๆ : หลังจากที่คุณพิมพ์fgคุณจะต้องให้สคริปต์เข้าบางอยู่แล้วก่อนที่มันจะดำเนินต่อไป ดังนั้นคำถามของฉัน ^Yผมก็ยังไม่เห็นจุดของ (ขอบคุณสำหรับการตอบกลับ!) :)
Wildcard

2

สถานการณ์เดียวที่ฉันนึกได้ (และถึงแม้ฉันจะไม่พบว่ามันน่าเชื่อถือมาก) คือถ้าคุณต้องการใช้การพิมพ์ล่วงหน้าสำหรับคำสั่งเชลล์ ใช้คำสั่งบางคำสั่งซึ่งจะอ่านอินพุตในอนาคต จากนั้นคุณสามารถ ^ Y ได้จากนั้นพิมพ์คำสั่ง shell ถัดไปที่คุณต้องการดำเนินการทันทีเมื่อคำสั่งที่กำลังรันหยุดทำงาน ฉันไม่คิดว่าฉันจะใช้สิ่งนี้ในหลายทศวรรษของการใช้ BSD Unix

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