两个编译的python程序是';t通过管道正确连接

两个编译的python程序是';t通过管道正确连接,python,terminal,pipe,Python,Terminal,Pipe,我正在编写两个非常简单的Python程序,并尝试在Linux(CentOS)上用管道连接它们。第一个(称为runner)只是打印,第二个(称为capture)应该从runner程序中读取这些打印语句并自己打印。但是,当我运行python runner.pyc | tee capture.pyc时,命令行中不会发生任何事情。它只是挂在某个进程上,并没有结束 我读了一些关于管道的书,但找不到与我的问题相关的东西 下面的代码包含一些print语句,只是为了验证哪个文件正在生成print语句,并在run

我正在编写两个非常简单的Python程序,并尝试在Linux(CentOS)上用管道连接它们。第一个(称为runner)只是打印,第二个(称为capture)应该从runner程序中读取这些打印语句并自己打印。但是,当我运行
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结果。