อินพุตมาตรฐานหลายรายการ? อย่างไร?


36

จากcommandlinefu โพสต์นี้ :

$ diff <(wget -q -O - URL1) <(wget -q -O - URL2)

ดูเหมือนว่าอินพุตมาตรฐานหลายรายการ แต่ถ้าฉันจำหลักสูตร Linux Porgramming ของฉันถูกต้อง --- นี่เป็นไปไม่ได้ ฉันคิดว่าตามคำนิยามอินพุตมาตรฐานคือสตรีมเดียว

อาจจะมี zilch เกี่ยวกับ stdin บ้างไหม? ใครสามารถอธิบายสิ่งนี้ให้ฉัน อาจมีลิงก์ไปยังเอกสารประกอบ

โบนัส:สคริปต์จะจัดการสตรีมหลายรายการเหล่านี้ได้อย่างไร หากใครบางคนสามารถให้ตัวอย่าง Python หรือ Perl นั่นจะเป็นประโยชน์มาก


1
คำถามที่ดี. ในกรณีที่คุณไม่ทราบมีเว็บไซต์ถามตอบ unix / linux: unix.stackexchange.com
Matt Ellen

2
เอกสารประกอบสำหรับการทดแทนกระบวนการ: gnu.org/software/bash/manual/bashref.html#Process-Substit
glenn jackman

หมายเหตุ: ใน Bash มัน<(…); ใน zsh =(…)ไวยากรณ์กระบวนการทดแทนคือ
Kamil Maciorowski

คำตอบ:


27

นี่ไม่ใช่อินพุตมาตรฐานหลายรายการ นี่คือ bash'ism ที่เรียกว่า 'การทดแทนกระบวนการ' http://tldp.org/LDP/abs/html/process-sub.html

มันสร้างไฟล์เทียม ( /dev/fd/something) สำหรับการทดแทนแต่ละครั้ง มันมีประโยชน์ทีเดียว คำสั่งสามารถอ่านเป็นกระแสได้เท่านั้นซึ่งหมายความว่าไม่สามารถย้อนกลับไปมาด้วย fseek มันจำเป็นต้องอ่านมันเป็นสตรีมของไบต์เช่นไพพ์

คำตอบโบนัส

คุณไม่จำเป็นต้องใช้สิ่งนี้มากเกินไป เท่าที่สคริปต์ของคุณเกี่ยวข้องจะได้รับชื่อไฟล์ที่ถูกต้องในบรรทัดคำสั่งที่สามารถเปิด () ed เหมือนอย่างอื่น diff /dev/fd/XX /dev/fd/YYในฐานะที่เป็นคนอื่นได้ว่าคุณจะเห็น หากคุณทำสถิติ () ในไฟล์หลอกเหล่านี้คุณจะเห็นว่าเป็นไปป์ที่มีชื่อและคุณควรปฏิบัติต่อด้วยซีแมนทิกส์ไพพ์ - นั่นคือไม่ใช่ fseek () หรือ ftell () หากคุณทำแบบทดสอบ stat () เพื่อดูว่าเป็นไฟล์ (เช่น[ -f $1 ]) สิ่งนี้จะแตกหรือไม่ - สิ่งนี้จะถูกนำไปใช้เป็นไพพ์ที่มีชื่อหลังจากทั้งหมด


อีกแหล่งอ้างอิงที่ดีสำหรับการทดแทนกระบวนการทุบตี - wiki.bash-hackers.org/syntax/expansion/proc_subst
studgeek

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

7

<(...)จะดำเนินการทดแทนในทุบตี เอาต์พุตของกระบวนการใน parens ถูกส่งไปยังไฟล์ descriptor เพิ่มเติมนอกเหนือจาก 3 ปกติและชื่อไฟล์จะถูกส่งกลับที่สอดคล้องกับ file descriptor นั้น ด้วยวิธีนี้เอาต์พุตของคำสั่งสามารถถูกใช้เป็นชื่อไฟล์ที่จะส่งผ่านไปยังคำสั่งอื่น


7

มีอยู่คนหนึ่งstdinและเป็นหนึ่งสำหรับแต่ละขั้นตอนstdout พวกเขามักจะเชื่อมต่อกับเทอร์มินัล แต่พวกเขาสามารถเปลี่ยนเส้นทางแยกจากกัน

ในตัวอย่างมีสองwgetกระบวนการมีส่วนร่วมของแต่ละคนที่ได้รับของตัวเองและstdin stdoutแต่ละwgetขั้นตอนการเขียนซึ่งเป็นของตน- stdoutการbashทดแทนกระบวนการนั้นจะ<(...)เชื่อมต่อstdoutกระบวนการกับไฟล์เทียมที่ไม่ซ้ำซึ่งdiffสามารถอ่านได้ โปรดทราบว่าการแทนที่กระบวนการทั้งสองให้ผลลัพธ์ไฟล์เทียมสองไฟล์! ดังนั้นจึงdiffเห็นบางสิ่งเช่น:

diff /dev/fd/XX /dev/fd/YY

ที่stdoutของwget -q -O - URL1การเชื่อมต่อกับ/dev/fd/XXและstdoutของที่จะwget -q -O - URL2/dev/fd/YY

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