กระบวนการย่อยของ Python Popen readline ก่อนปิด stdin

Sep 07 2020
import subprocess as sp

p = sp.Popen("/bin/cat", stdin=sp.PIPE, stdout=sp.PIPE)

p.stdin.write(b"foobaz!\n")
p.stdin.close()
print(p.stdout.readline())

รหัสนี้ทำงานได้ตามที่คาดไว้ (cat สะท้อน stdin และเราสามารถอ่าน stdout ได้)

ถ้าเราแสดงความคิดเห็นออกมาp.stdin.close()ที่.readline()บล็อกไปเรื่อย ๆ การดำเนินการนี้จะเป็นการเรียกแบบเดียวกัน.read(1)แทน มีวิธีการอ่านบรรทัดโดยใช้โมดูลกระบวนการย่อยโดยไม่ต้องส่ง EOF ไปยัง stdin หรือไม่?

ฉันทราบดีว่ามีห้องสมุดอื่น ๆ ที่อาจแก้ปัญหาของฉันได้และกำลังตรวจสอบอยู่เช่นกัน สำหรับคำถามนี้ฉันแค่อยากรู้ว่าsubprocessมีความสามารถนี้หรือไม่และจะประสบความสำเร็จได้subprocessอย่างไร

คำตอบ

1 alani Sep 07 2020 at 12:28

ปัญหาอยู่ที่การบัฟเฟอร์ คุณสามารถใช้bufsize=1if you also use universal_newlines=True(แม้ว่าคุณจะเขียนสตริงแทนไบต์):

p = sp.Popen("/bin/cat", stdin=sp.PIPE, stdout=sp.PIPE, 
             bufsize=1, universal_newlines=True)
p.stdin.write("foobaz!\n")
print(p.stdout.readline())

ข้างต้นได้รับการทดสอบใน Python 3.5.2 หมายเหตุ - ฉันได้อ่านคำตอบสำหรับคำถามที่ไม่เกี่ยวข้องแยกต่างหากซึ่งชี้ให้เห็นว่าใน Python เวอร์ชันล่าสุดtext=Trueนั้นเทียบเท่าได้universal_newlines=Trueแต่ไม่มีการติดตั้งล่าสุดให้ลองใช้ในขณะที่เขียน