เมื่อtrue
ออกจากด้านการอ่านของไปป์ถูกปิด แต่yes
ยังคงพยายามเขียนไปยังด้านการเขียน สภาพนี้เรียกว่า "ท่อเสีย" และจะทำให้เมล็ดเพื่อส่งสัญญาณไปยังSIGPIPE
yes
เนื่องจากyes
ไม่มีอะไรพิเศษเกี่ยวกับสัญญาณนี้มันจะถูกฆ่า ถ้ามันไม่สนใจสัญญาณของการโทรจะล้มเหลวด้วยรหัสข้อผิดพลาดwrite
EPIPE
โปรแกรมที่ต้องเตรียมพร้อมที่จะแจ้งให้ทราบEPIPE
และหยุดเขียนไม่เช่นนั้นโปรแกรมจะเข้าสู่วงวนไม่สิ้นสุด
หากคุณทำstrace yes | true
1คุณจะเห็นเคอร์เนลเตรียมพร้อมสำหรับความเป็นไปได้ทั้งสองอย่าง:
write(1, "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 4096) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=17556, si_uid=1000} ---
+++ killed by SIGPIPE +++
strace
กำลังดูกิจกรรมผ่านดีบักเกอร์ API ซึ่งจะบอกก่อนเกี่ยวกับการเรียกระบบกลับมาพร้อมกับข้อผิดพลาดจากนั้นเกี่ยวกับสัญญาณ yes
แม้ว่าจากมุมมองของสัญญาณจะเกิดขึ้นก่อน (ในทางเทคนิคสัญญาณจะถูกส่งหลังจากเคอร์เนลส่งคืนการควบคุมไปยังพื้นที่ผู้ใช้ แต่ก่อนที่จะดำเนินการคำสั่งเครื่องเพิ่มเติมดังนั้นwrite
ฟังก์ชัน "wrapper" ในไลบรารี C จะไม่ได้รับโอกาสในการตั้งค่าerrno
และกลับสู่แอปพลิเคชัน)
1น่าเศร้าที่strace
เป็นลินุกซ์ที่เฉพาะเจาะจง Unixes ที่ทันสมัยส่วนใหญ่มีคำสั่งบางอย่างที่ทำสิ่งที่คล้ายกัน แต่มักจะมีชื่อที่แตกต่างกันมันอาจจะไม่ถอดรหัสอาร์กิวเมนต์ syscall เป็นอย่างละเอียดและบางครั้งมันก็ใช้งานได้สำหรับรูทเท่านั้น
yes | tee >(true) >/dev/null
จะทำตามที่คุณคาดหวัง btw ตามที่tee
ดำเนินต่อไปจนกว่านักเขียนทุกคนจะตายดังนั้นการtrue
ออกจะไม่รบกวนมันอย่างสิ้นเชิง