รับ stdin จากไปป์ที่มีชื่อ


10

สิ่งที่ฉันพยายามทำคือใช้ python ในหน้าต่างเทอร์มินัลและเปลี่ยนเส้นทางมันเป็น stdin จากไพพ์ที่มีชื่อ จากนั้นฉันเขียนไปที่ไปป์ที่มีชื่อในเทอร์มินัลอื่นและมีคำสั่งที่รันบนหลาม

อาคาร 1:

mkfifo p1
python < p1

อาคาร 2:

echo -n "print \"Hello World\"" > p1

สิ่งที่เกิดขึ้นคือ - หลามพิมพ์Hello Worldและออกจาก สิ่งที่ฉันต้องการจะทำคือให้หลามใช้คำสั่งถัดไป ฉันจะทำสิ่งนี้ในเปลือกได้อย่างไร

คำตอบ:


10

คุณจำเป็นต้อง

  • เรียกใช้ python แบบโต้ตอบแม้ว่า stdin จะไม่ใช่ terminal: use python -i
  • เปิดปลายการเขียนของไพพ์ค้างไว้มิฉะนั้นไพ ธ อนจะตรวจจับ EOF และออก

ดังนั้น:

python -i < p1

และที่อื่น ๆ :

exec 3> p1
echo '1j*1j' >&3
...
# and when done, close that file descriptor so python sees the EOF:
exec 3>&-

ขอบคุณ! มันได้ผล ฉันไม่คุ้นเคยกับสิ่งที่คุณทำ คุณช่วยเพิ่มรายละเอียดในคำตอบเพื่ออธิบายสิ่งที่เกิดขึ้นได้ไหม กำลังexec 3> p1ทำอะไร&3และ & คือexec 3> &1อะไร ขอบคุณ.
ลอร์ดโลห์

1
คำตอบของคุณทำให้ฉันนึกถึงแบนเนอร์นี้ - sphotos-b.xx.fbcdn.net/hphotos-ash4/ ......มันเป็นรูปหน้าปกของเพื่อนใน facebook :-)
Lord Loh

คำถามจะexec 3>&-ทำงานเหมือนกับexec 3>&1ที่นี่หรือไม่
Wildcard

1
@ บัตรฉันสงสัยว่าฉันตั้งใจจะเขียน3>&-ที่นี่ 3>&1จะทำงานได้ดี แต่ไม่เข้าท่า ขอบคุณ
Stéphane Chazelas

5

คุณสามารถใช้tail -fเพื่อให้ฟีฟ่าเปิดหลังจากechoเขียนไป

tail -n1 -f p1 | python

ทำไมถึงใช้งานได้

pythonp1คืออ่านจาก เมื่อถึงจุดสิ้นสุดของไฟล์มันจะหยุดอ่าน นี่เป็นพฤติกรรมปกติของการอ่านไฟล์แม้ว่าไฟล์จะเป็นไพพ์ที่มีชื่อ tailด้วยการ-fตั้งค่าสถานะ (ติดตาม) จะทำให้การอ่านจากไฟล์หลังจากถึงจุดสิ้นสุด


ฉันลองecho "print \"Hello World\" " > p1ในสถานีที่สองและไม่มีอะไรเกิดขึ้น - แต่สถานีก็ไม่ได้ถูกปิดกั้นอย่างใดอย่างหนึ่ง เทอร์มินัลกับไพ ธ อนยังคงถูกบล็อกจนกว่าฉัน^cจะออกจากมันและยุติการทำงานของไพ ธ อนด้วยข้อความขัดจังหวะโดยคีย์บอร์ดที่แสดงโดยไพ ธ อน
ลอร์ดโลห์

ฉันใช้tail -fเคล็ดลับนี้เมื่อคลายการแยกไฟล์เก็บถาวร tar แบบแบ่งบล็อกผ่านไพพ์ที่มีชื่อ มันทำงานได้อย่างยอดเยี่ยม
Mael

2

คุณต้องส่งโปรแกรมทั้งหมดในครั้งเดียว

เมื่อคุณเรียกใช้รันpython < p1เชลล์กำลังรออินพุตก่อนเรียกใช้งานไพ ธ อน นั่นคือไพ ธ อนไม่ได้เริ่มดำเนินการเลยจนกว่าเชลล์ข้อมูลทั้งหมดจะถูกอ่านโดยเชลล์และจากนั้นจะถูกส่งผ่านไปอย่างpythonเต็มที่

แม้แต่การรันpython -u p1แทน (นั่นคือ unbuffered และอ่านจากไฟล์p1) pythonจะพยายามอ่านไฟล์ทั้งหมดก่อนที่จะดำเนินการใด ๆ

ลองการทดลองนี้

อาคาร 1:

mkfifo p1
python < p1

อาคาร 2:

cat > p1
print "Hello World"
print "Hello World"

คุณจะเห็นว่าคุณสามารถส่งได้หลายบรรทัด แต่หลามในเทอม 1 ไม่ได้ทำอะไรเลย ตอนนี้กด+ctrl Dโปรแกรมทั้งหมดทำงานในครั้งเดียว

ดังนั้นเพื่อสรุปถ้าคุณต้องการให้ไพ ธ อนอ่านจากไพพ์คุณต้องส่งโปรแกรมทั้งหมด คุณไม่สามารถใช้ python แบบโต้ตอบได้


1

อาจใช้วิธีหางดีกว่า (ยืดหยุ่นมากกว่า) แต่เป็นทางเลือก:

{ echo -n "print \"Hello World\""; cat; } > p1

สิ่งนี้ไม่ทำงานตามที่ฉันต้องการ -nอาจมีการลบ o และหลังจากนั้น 0 เทอร์มินัลที่มีechoคำสั่งถูกบล็อก 1. python ไม่ดำเนินการคำสั่งจนกว่าฉันจะกด^cในechoเทอร์มินัลและกระบวนการทั้งคู่ยุติลง
ลอร์ดโลห์

1
@LordLoh อาจเป็นปัญหาบัฟเฟอร์ ไพ ธ อนอาจจะรันคำสั่งหากมีการสร้างเอาต์พุตเพียงพอเพื่อให้บรรทัดแรกถูกเขียนไปที่ FIFO ในที่สุด แต่เนื่องจากมีวิธีแก้ปัญหาที่ใช้งานได้จึงไม่มีเหตุผลที่จะพยายามแก้ไขปัญหานี้
Hauke ​​Laging
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.