ฉันได้รับข้อผิดพลาด "broken pipe" จาก Xcode หนึ่งครั้งมากเกินไป ตอนนี้ฉันอยากรู้รู้ว่าท่อคืออะไร
แนวคิดของ "ไพพ์" คืออะไรและมันจะ "แตกหัก" ได้อย่างไร?
ฉันได้รับข้อผิดพลาด "broken pipe" จาก Xcode หนึ่งครั้งมากเกินไป ตอนนี้ฉันอยากรู้รู้ว่าท่อคืออะไร
แนวคิดของ "ไพพ์" คืออะไรและมันจะ "แตกหัก" ได้อย่างไร?
คำตอบ:
ไปป์เป็นเพียงกลไกการสื่อสารระหว่างกระบวนการ (IPC) ที่ใช้เชื่อมต่อเอาต์พุตมาตรฐานของกระบวนการหนึ่งไปยังอินพุตมาตรฐานของอีกกระบวนการหนึ่ง
ตัวอย่างคือเมื่อคุณต้องการค้นหาไฟล์สำหรับคำว่า "pax":
cat filename | grep pax
และใช่ฉันรู้ว่าคุณสามารถเรียกgrep
ใช้ไฟล์ได้โดยตรง แต่นั่นไม่ได้อธิบายว่ามันทำงานอย่างไร
สิ่งนี้จะเชื่อมต่อเอาต์พุตมาตรฐานของcat
คำสั่งกับอินพุตมาตรฐานของgrep
คำสั่ง cat
ส่งเนื้อหาของไฟล์ไปยังเอาต์พุตมาตรฐานและgrep
อ่านไฟล์ (ในกรณีนี้) จากอินพุตมาตรฐาน ด้วยการเชื่อมต่อกระบวนการต่างๆเข้าด้วยกันเช่นนี้คุณสามารถสร้างเครื่องมือของคุณเองซึ่งประกอบด้วยกลุ่มส่วนท่อจำนวนเท่าใดก็ได้ สิ่งที่ชอบ:
show_users | grep pax | awk -F: '{print $4}' | tr '[a-z]' '[A-Z]' | cut -c1-20
เสียท่อเป็นหนึ่งในสถานที่ที่ (ปกติ) รับของข้อมูลที่มีการปิดการเชื่อมต่อในขณะที่ผู้ส่งยังคงพยายามที่จะส่งผ่านสิ่ง
ตัวอย่างเช่นหากคุณส่งไฟล์ขนาดใหญ่ผ่านโปรแกรมวิทยุติดตามตัว (เพื่อดูทีละหน้า):
cat myfile | pager
และจากนั้นทำสิ่งCTRL-BREAKนี้อาจทำให้pager
กระบวนการปิดท่ออินพุตก่อนที่จะcat
ใช้งานได้ นั่นเป็นความเป็นไปได้อย่างหนึ่งที่จะทำให้ท่อแตก
จากการค้นหาโดยคร่าวๆของ Googleปัญหานี้ดูเหมือนจะเกี่ยวข้องกับการปรับใช้ Ad-hoc และวิธีแก้ปัญหาที่ได้รับมักจะรวมถึงการออกจากซอฟต์แวร์ส่วนใหญ่ของคุณและการรีบูตอุปกรณ์ส่วนใหญ่ของคุณ
นี่อาจร้ายแรงพอที่จะรายงานปัญหาให้ Apple ทราบ นักพัฒนามากขึ้นที่บ่นเกี่ยวกับมันมีโอกาสมากขึ้นที่จะทำเพื่อแก้ไข
pr -e4 -n ten-thousand-lines.c | sed 10q
จบลงด้วยท่อแตก ไม่ว่าจะเป็นการpr
รบกวนจิตใจหรือไม่ที่จะบอกคุณว่าสัญญาณ SIGPIPE เป็นอีกเรื่องหนึ่ง มันอาจเพียงแค่ออกจากผลลัพธ์ของสัญญาณ (สร้างสถานะทางออกที่ไม่ใช่ศูนย์)
|
ตัวละครมักจะเรียกว่าท่อ ในเชลล์ UNIX ต่างๆ (ที่ฉันรู้) มันสามารถใช้เพื่อไพพ์เอาต์พุตของคำสั่งหนึ่งไปยังอินพุตของอีกอันหนึ่ง
cat myfile.txt | head
head
คำสั่งเพียงแสดงให้เห็นเพียงไม่กี่บรรทัดแรกของปัจจัยการผลิต ณ จุดนั้นมันปิดอินพุตของมัน สิ่งนี้ทำให้เกิดปัญหาสำหรับคำสั่งที่สร้างอินพุต มันเขียนถึงที่ไหน? เมื่อใดก็ตามที่เรามีสถานการณ์นี้หรือสถานการณ์เมื่อกระบวนการเขียนสิ้นสุดลงก่อนที่ผู้อ่านจะผ่านก็จะเรียกว่า "ท่อเสีย"
เพื่อป้องกันไม่ให้cat
คำสั่งจากเอ้อระเหยตลอดมาตรฐาน UNIX กำหนดสัญญาณพิเศษ ( SIGPIPE , สัญญาณ 13 ) cat
ที่จะส่งไปยัง การกระทำเริ่มต้นสำหรับสัญญาณนี้คือการฆ่ากระบวนการซึ่งทำให้cat
จบอย่างสวยงาม
ดูเหมือนว่าแอปพลิเคชันที่คุณใช้ได้ติดตั้งตัวจัดการสัญญาณสำหรับสัญญาณทั้งหมดรวมถึง SIGPIPE ซึ่งสร้างข้อความป๊อปอัปขนาดเล็กที่คุณเห็น
ข้อผิดพลาดนี้ดูเหมือนว่าจะเกิดขึ้นค่อนข้างบ่อย /programming/490366/ad-hoc-deployment-issue-putpkt-write-failed-broken-pipe เป็น "... ข้อผิดพลาดภายในความสามารถของ Xcode ในการพูดคุยกับโทรศัพท์ของคุณไม่ได้ หมายความว่าคุณทำอะไรผิดมันเป็นข้อผิดพลาดในระบบการพัฒนา "
ไปป์เป็นกลไก IPC บนระบบ Unix ไปป์มีสองปลายอ่านจบและเขียนสิ้นสุด ข้อมูลที่เขียนลงในการเขียนสิ้นสุดสามารถอ่านได้จากการอ่านและออกมาในลำดับที่มันถูกเขียน
ในโลกบรรทัดคำสั่ง Unix ไพพ์เป็นวิธีการเชื่อมโยงโปรแกรมเข้าด้วยกันเพื่อให้งานสำเร็จ ยกตัวอย่างเช่นsed 's/foo/bar/g' fred.txt | grep -e 'bar.*baz'
จะอ่านในไฟล์fred.txt
แทนที่ทุกกรณีของสตริงfoo
กับสตริงbar
แล้วผลการค้นหาสำหรับเส้นที่มีตามด้วยหมายเลขของตัวละครบางส่วนแล้วbar
baz
แน่นอนว่าไม่มีประโยชน์มากนัก แต่ฉันแน่ใจว่าถ้าคุณคิดเกี่ยวกับมันที่คุณสามารถดูวิธีที่คุณสามารถนำไปใช้กับการใช้งานที่น่าสนใจทุกประเภทโดยเฉพาะอย่างยิ่งเมื่อคุณมีโปรแกรมเช่นawk
หรือperl
ตามที่คุณต้องการ
ระบบท่อเป็นส่วนหนึ่งของ Unix ตั้งแต่เริ่มต้น และถ้ากระบวนการในไปป์ไลน์ของคุณออกจากคุณมักจะต้องการให้โปรแกรมทั้งหมดในไปป์ไลน์ออกจาก ซึ่งหมายความว่าโดยค่าเริ่มต้นกระบวนการที่เขียนลงในไพพ์คือกระบวนการที่ส่วนท้ายการอ่านหายไปจะได้รับSIGPIPE
สัญญาณ และถ้ามันปิดกั้นสัญญาณนั้นwrite
จะยังคงล้มเหลวด้วยข้อผิดพลาดชนิดพิเศษที่ระบุว่าท่อมี 'เสีย'
การจัดการเริ่มต้นของการSIGPIPE
ฆ่ากระบวนการที่ได้รับ และถ้าไม่ใช่ 'หัว' ของไปป์ไลน์SIGPIPE
สิ่งทั้งหมดก็จะกระจายกลับไปที่โซ่
สิ่งที่ Xcode กำลังบ่นก็คือมันเริ่มบางโปรแกรมย่อยเพื่อทำบางสิ่งบางอย่างกับไพพ์ที่นำไปสู่และโปรแกรมย่อยนั้นก็ตายโดยไม่คาดคิดทำให้ท่อแตก
ไปป์ที่“ แตก” คือปลายที่ปลายด้านหนึ่งถูกปลายอีกด้านหนึ่งclose()
กำลังถูกอ่านหรือเขียนจาก ตัวอย่างเช่นในคำสั่งเชลล์ต่อไปนี้:
cat foo | less
cat
กระบวนการถือสิ้นสุดการเขียนของท่อและless
กระบวนการอ่านหนึ่ง หากกระบวนการอ่านปิดท่อไปป์นั้นเสีย (และไม่มีประโยชน์อะไรเลย) กระบวนการตัวเขียนจะได้รับข้อผิดพลาด“ ท่อแตก” จากระบบปฏิบัติการ
cat
เห็นได้ชัดว่าจะเกิดขึ้นทันทีที่เสร็จสิ้น) ผู้อ่านจะเห็นจุดสิ้นสุดไฟล์ปกติ