两个编译的python程序是';t通过管道正确连接
我正在编写两个非常简单的Python程序,并尝试在Linux(CentOS)上用管道连接它们。第一个(称为runner)只是打印,第二个(称为capture)应该从runner程序中读取这些打印语句并自己打印。但是,当我运行两个编译的python程序是';t通过管道正确连接,python,terminal,pipe,Python,Terminal,Pipe,我正在编写两个非常简单的Python程序,并尝试在Linux(CentOS)上用管道连接它们。第一个(称为runner)只是打印,第二个(称为capture)应该从runner程序中读取这些打印语句并自己打印。但是,当我运行python runner.pyc | tee capture.pyc时,命令行中不会发生任何事情。它只是挂在某个进程上,并没有结束 我读了一些关于管道的书,但找不到与我的问题相关的东西 下面的代码包含一些print语句,只是为了验证哪个文件正在生成print语句,并在run
python runner.pyc | tee capture.pyc
时,命令行中不会发生任何事情。它只是挂在某个进程上,并没有结束
我读了一些关于管道的书,但找不到与我的问题相关的东西
下面的代码包含一些print语句,只是为了验证哪个文件正在生成print语句,并在runner.py中休眠3秒钟,这样我就不会生成过长的输出
runner.py代码:
import time
x = 0;
while True:
print(x)
x = x + 1
print("running file")
time.sleep(3)
import sys
import time
while True:
line = sys.stdin.readline()
print(line)
print("capture file")
capture.py代码:
import time
x = 0;
while True:
print(x)
x = x + 1
print("running file")
time.sleep(3)
import sys
import time
while True:
line = sys.stdin.readline()
print(line)
print("capture file")
有人能给我解释一下我做错了什么,或者给我指出正确的方向吗 这个问题是由一堆东西引起的(参见对这个问题的评论)。但在runner程序中,输出没有刷新。只需添加一个
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
...
[bash] python3 ./runner.py | python3 ./capture.py
如果没有刷新,可能会有一些输出后一段时间,但我不会等待足够长的时间来发现。通常在print()
上的冲洗在行尾完成。但对于管道,至少在Linux上,分配了4KB的缓冲区。有一个。但是管道缓冲依赖于操作系统,所以很难确切知道发生了什么
使用缓冲是因为它浪费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 | cat
0
running file
1
running file
...
[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]
您需要一种方法来检查捕获端的文件结尾。您使用的
tee
错误(不确定为什么使用它):command | tee filename
将命令的输出的副本转移到filename
,因此在这种情况下,您只需覆盖文件capture.pyc
,而不运行“捕获”程序。在最简单的情况下,您应该运行python runner.py | python capture.py
(也不确定为什么要运行.pyc
文件)。中间应该是python runner.py | tee some_file.txt | python capture.py
@mkrieger1当我尝试python runner.py | python capture.py
时,它仍然挂起在命令提示符下而没有完成。当我控制-C out时,它给我消息:Traceback(最近的调用最后一次):Traceback(最后一次调用):文件“capture.py”,第5行,文件“runner.py”,第9行,in time.sleep(3)line=sys.stdin.readline()KeyboardInterrupt KeyboardInterrupt
@mkrieger1公认的答案解决了我的问题。谢谢你指出我有多个问题,我将逐一研究。你能描述一下刷新的具体功能吗,以及没有刷新为什么会有问题吗?@Mr.Mips-我添加了一些简单的注释。很难确切知道发生了什么,因为观察到的操作是Python、BASH(可能是libc)和Linux的nett结果。