คำถามในหนังสือแจ้งการรับรางวัลปัจจุบัน:
ตัวอย่างทั่วไปนั้นซับซ้อนเกินไป ใครบางคนช่วยอธิบายวิธีการใช้ตัวอย่างต่อไปนี้ได้ไหม?diff <(cat "$2" | xz -d) <(cat "$1" | xz -d)
ดูเหมือนว่าจะมีคำตอบที่นี่
ดังที่แสดงในคำตอบของ Gillesแนวคิดทั่วไปคือการส่งเอาต์พุตของคำสั่ง "producer" ไปยังไฟล์อุปกรณ์ใหม่1ในระยะต่าง ๆ ของไปป์ไลน์ทำให้พวกเขาพร้อมใช้งานกับคำสั่ง "consumer" ซึ่งอาจใช้ชื่อไฟล์เป็นอาร์กิวเมนต์ ( สมมติว่าระบบของคุณอนุญาตให้คุณเข้าถึง file descriptors as /dev/fd/X)
วิธีที่ง่ายที่สุดในการบรรลุสิ่งที่คุณค้นหาน่าจะเป็น:
xz -cd file1.xz | { xz -cd file2.xz | diff /dev/fd/3 -; } 3<&0
(ใช้file1.xzแทน"$1"การอ่านได้และxz -cdแทนที่จะใช้cat ... | xz -dเพราะคำสั่งเดียวก็เพียงพอแล้ว)
เอาต์พุตของคำสั่ง "producer" แรกxz -cd file1.xzจะถูกไพพ์ไปยังคำสั่งผสม ( {...}); แต่แทนที่จะถูกบริโภคทันทีที่เข้ามาตรฐานของคำสั่งต่อไปก็คือการทำซ้ำเพื่ออธิบายไฟล์และทำให้สามารถเข้าถึงได้ทุกอย่างภายในคำสั่งผสมเป็นดังนั้น3 /dev/fd/3การส่งออกของคำสั่งที่สอง "ผู้ผลิต" ที่xz -cd file2.xzซึ่งไม่กินไม่เข้ามาตรฐานของมันมิได้อะไรจากไฟล์อธิบาย3เป็นแล้วประปาคำสั่ง "ผู้บริโภค" ซึ่งอ่านจากอินพุตมาตรฐานและจากdiff/dev/fd/3
การทำสำเนา Piping และ File Descriptor อาจถูกเพิ่มเพื่อให้ไฟล์อุปกรณ์สำหรับคำสั่ง "producer" ได้มากเท่าที่ต้องการเช่น:
xz -cd file1.xz | { xz -cd file2.xz | { diff /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
แม้ว่ามันอาจจะไม่เกี่ยวข้องกับบริบทของคำถามเฉพาะของคุณ แต่ก็เป็นที่น่าสังเกตว่า:
cmd1 <(cmd2) <(cmd3), cmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0และ( cmd2 | ( cmd3 | ( cmd1 /dev/fd/3 /dev/fd/4 ) 4<&0 ) 3<&0 )มีผลกระทบที่อาจเกิดขึ้นแตกต่างกันในสภาพแวดล้อมการดำเนินการเริ่มต้น
ขัดกับสิ่งที่เกิดขึ้นในcmd1 <(cmd2) <(cmd3), cmd3และcmd1ในcmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0จะไม่สามารถที่จะอ่านป้อนข้อมูลใด ๆ จากผู้ใช้ ที่จะต้องมีตัวอธิบายไฟล์เพิ่มเติม ตัวอย่างเช่นเพื่อให้ตรงกับ
diff <(echo foo) <(read var; echo "$var")
คุณจะต้องการอะไรเช่น
{ echo foo | { read var 0<&9; echo "$var" | diff /dev/fd/3 -; } 3<&0; } 9<&0
1 เพิ่มเติมเกี่ยวกับพวกเขาสามารถพบได้บน U & L เช่นในการทำความเข้าใจ / dev และ subdirs และไฟล์