我正在创建一个脚本,其中包含一些其他脚本输出管道。另一个脚本需要一段时间才能完成,并将进度与我要解析的数据一起打印到控制台上。
由于我将结果传递给我的脚本,我希望能够做两件事。随着我的输入,我想在屏幕上回应它。命令完成后,我希望有一个通过stdin传递的行列表。
我的第一个是使用简单的
for line in sys.stdin:
sys.stdout.write(line + '\n')
lines.append(line)
sys.stdout.flush()
但令我惊讶的是,命令等待直到stdin命中EOF,直到它开始产生线条。
我目前的解决方法是:
line = sys.stdin.readline()
lines = []
while line:
sys.stdout.write(line.strip() + '\n')
lines.append(line.strip())
sys.stdout.flush()
line = sys.stdin.readline()
但是这并不总是等到使用整个输入。
还有其他办法吗? for解决方案的行为方式似乎很奇怪。
答案 0 :(得分:1)
其他人已经告诉过你有关无缓冲输出的信息。我只想补充一些想法:
stderr
输出通常是无缓冲的将中间输出委托给特殊工具更简单。例如,有一个tee实用程序,它允许拆分前一个命令的stdout。假设您在bash
,您可以立即将中间输出打印到stdout,并使用process substitution而不是打印到文件(而不是awk,您将调用您的python脚本):
$ python -c 'for i in range(5): print i+1' | tee >( awk '{print "from awk", $0**2 }')
1
2
3
4
5
from awk 1
from awk 4
from awk 9
from awk 16
from awk 25
答案 1 :(得分:0)
你需要在你的python程序中创建1)stdin和2)在管道的相反一侧的stdout都是行缓冲的。为了得到这个
1)在你的程序中使用stdin = os.fdopen(sys.stdin.fileno(), 'r', 1)
;
2)使用stdbuf -oL
更改其他程序输出的缓冲模式:
stdbuf -oL otherprogram | python yourscript.py