我正在编写两个非常简单的Python程序,并尝试将它们与Linux(CentOS)上的管道连接。第一个(称为运行程序)仅打印,而第二个(称为捕获程序)应该从运行程序中读取这些打印语句,然后自行打印。但是当我运行python runner.pyc | tee capture.pyc
时,命令行没有任何反应。它只是挂在某个过程上而不会结束。
我已经对管道进行了一些阅读,但是找不到与我的问题相关的东西。
下面的代码包含一些打印语句,这些语句仅用于验证哪个文件正在生成打印语句,并且在Runner.py中睡眠3秒钟,因此我不会产生过长的输出。
runner.py代码:
import time
x = 0;
while True:
print(x)
x = x + 1
print("running file")
time.sleep(3)
capture.py代码:
import sys
import time
while True:
line = sys.stdin.readline()
print(line)
print("capture file")
有人可以向我解释我做错了什么,或者指出正确的方向吗?
答案 0 :(得分:1)
该问题是由一堆东西引起的(请参阅问题注释)。但是在运行程序中,不会刷新输出。只需添加flush=True
(仅适用于Python3)即可解决此问题,并且运行通过了cat
测试。
#! /usr/bin/env python3
import time
x = 0;
while True:
print(x)
x = x + 1
print("running file", flush=True)
time.sleep(1)
测试:
[bash] python3 ./runner.py | cat
0
running file
1
running file
...
没有刷新,过一会儿可能会有一些输出,但是我不会等很久才找到答案。通常,print()
上的刷新是在行尾进行的。但是至少在Linux上,使用管道分配了4 KB的缓冲区。有一个way to un-buffer this。但是管道缓冲取决于操作系统,因此很难确切知道发生了什么。
之所以使用缓冲,是因为它浪费CPU资源,一个字符一个字符地处理数据,而不是一次处理整个数据块。
在捕获方面,sys.stdin.readline()
通常返回0字节读取,因此更好地处理此问题:
#! /usr/bin/env python3
import sys
import time
while True:
line = sys.stdin.readline()
if ( len(line) > 0 ):
print( "Read %u: [%s]" % ( len(line), line.strip() ) )
测试:
[bash] python3 ./runner.py | python3 ./capture.py
礼物:
python3 ./runner.py | python3 ./capture.py
Read 2: [0]
Read 13: [running file]
Read 2: [1]
Read 13: [running file]
您将需要一种方法来在捕获端检查文件结尾。