从管道循环进程中读取Python的标准输入

3
如何在Python中生成或Popen子进程并实时处理其输出?
子进程的输出是根据其他系统事件随机打印的。
以下“示例”会挂起: $./print.sh | ./echo.py 挂起。

print.sh

#!/bin/bash

while [ 1 ]; do
echo 'A'
sleep 1
done

echo.py

#!/usr/bin/python
import sys

for line in sys.stdin:
  print line

在你的问题中更新操作系统的详细信息。 - tuxuday
@tuxuday 显然是类Unix系统(Linux,Mac OS X),因为他正在使用bash。回答问题还需要知道更多吗? - Lauritz V. Thaulow
2个回答

2
它不会挂起。由于写入管道,echo/shell决定以块缓冲而不是行缓冲模式执行I/O操作。如果你等待足够长的时间,或者从shell脚本中删除sleep 1,你会看到来自A的输出确实传递过来了。
有两种可能的解决方案:
  1. 修改子进程的程序,使其在写入足够多的输出供Python程序处理时刷新其缓冲区。
  2. 使用伪终端(PTY)代替管道。pexpect就是这样做的,它将大部分复杂性隐藏起来。但它并不能完全取代subprocess

重点是我需要实时处理输出。此外,在生产中,我使用一个我无法控制的程序,即刷新其stdout。我想要做的是生成/ Popen一个inotifywait进程来监视是否将新文件写入目录。如果写入了新文件,则实时获取inotify的输出并处理刚刚写入的文件。 - DrWolf

0

检查这段代码片段是否正常运行。

cat ech.sh

#!/bin/bash

while [ 1 ]; do
echo -n 'A'
sleep 1
done

cat in_read.py

#!/usr/bin/python
import sys
import os

while True:
  print os.read(0,1)

是的,它可以。我会在生产环境中进行测试。谢谢。 - DrWolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接