มันง่ายมากที่จะเห็นภาพสิ่งต่าง ๆ ถ้าคุณคิดว่าเกิดอะไรขึ้นกับ "การเปลี่ยนเส้นทาง" และ "ท่อ" การเปลี่ยนเส้นทางและไปป์ในทุบตีทำสิ่งหนึ่ง: แก้ไขที่ตัวอธิบายไฟล์กระบวนการ 0, 1 และ 2 ชี้ไปที่ (ดู / proc / [pid] / fd / *)
เมื่อเป็นท่อหรือ "|" โอเปอเรเตอร์ปรากฏอยู่บนบรรทัดคำสั่งสิ่งแรกที่เกิดขึ้นคือทุบตีสร้าง Fifo และชี้ให้คำสั่ง FD 1 ของฝ่ายซ้ายด้านซ้ายมาที่ Fifo นี้และชี้ให้คำสั่ง FD 0 ของฝ่ายขวาเหมือนกัน
ถัดไปตัวดำเนินการเปลี่ยนเส้นทางสำหรับแต่ละด้านจะถูกประเมินจากซ้ายไปขวาและการตั้งค่าปัจจุบันจะถูกใช้เมื่อใดก็ตามที่การทำซ้ำของ descriptor เกิดขึ้น สิ่งนี้มีความสำคัญเนื่องจากตั้งแต่ตั้งค่าท่อไปก่อน FD1 (ด้านซ้าย) และ FD0 (ด้านขวา) จะเปลี่ยนไปจากสิ่งที่พวกเขาอาจเคยเป็นมาก่อนและการทำซ้ำของสิ่งเหล่านี้จะสะท้อนถึงความจริงนั้น
ดังนั้นเมื่อคุณพิมพ์สิ่งต่อไปนี้:
command 2>&1 >/dev/null | grep 'something'
นี่คือสิ่งที่เกิดขึ้นตามลำดับ:
- สร้าง pipe (fifo) "คำสั่ง FD1" ถูกชี้ไปที่ไพพ์นี้ "grep FD0" ยังชี้ไปที่ท่อนี้
- "command FD2" ถูกชี้ไปที่ตำแหน่งปัจจุบันของ "command FD1" (ไปป์)
- "คำสั่ง FD1" ถูกชี้ไปที่ / dev / null
ดังนั้นเอาต์พุตทั้งหมดที่ "คำสั่ง" เขียนไปยัง FD 2 (stderr) ทำให้ไปยังไพพ์และอ่านโดย "grep" ที่อีกด้านหนึ่ง เอาต์พุตทั้งหมดที่ "คำสั่ง" เขียนไปยัง FD 1 (stdout) ทำให้มันเป็น / dev / null
หากคุณรันสิ่งต่อไปนี้แทน:
command >/dev/null 2>&1 | grep 'something'
นี่คือสิ่งที่เกิดขึ้น:
- ไพพ์ถูกสร้างขึ้นและ "คำสั่ง FD 1" และ "grep FD 0" จะชี้ไปที่
- "คำสั่ง FD 1" ถูกชี้ไปที่ / dev / null
- "command FD 2" จะชี้ไปที่จุดใด FD 1 ปัจจุบัน (/ dev / null)
ดังนั้น stdout และ stderr ทั้งหมดจาก "command" ไปที่ / dev / null ไม่มีอะไรไปที่ไพพ์ดังนั้น "grep" จะปิดลงโดยไม่แสดงอะไรบนหน้าจอ
นอกจากนี้โปรดทราบว่าการเปลี่ยนเส้นทาง (ตัวอธิบายไฟล์) สามารถเป็นแบบอ่านอย่างเดียว (<), เขียนอย่างเดียว (>) หรืออ่านเขียน (<>)
บันทึกสุดท้าย การเขียนโปรแกรมไปยัง FD1 หรือ FD2 นั้นขึ้นอยู่กับโปรแกรมเมอร์หรือไม่ แนวปฏิบัติที่ดีในการเขียนโปรแกรมกำหนดว่าข้อความแสดงข้อผิดพลาดควรไปที่ FD 2 และเอาท์พุทปกติไปที่ FD 1 แต่คุณมักจะพบว่าการเขียนโปรแกรมเลอะเทอะที่ผสมทั้งสองหรือละเว้นการประชุม