两个已编译的python程序未通过管道正确连接

时间:2019-01-13 22:38:07

标签: python terminal pipe

我正在编写两个非常简单的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")

有人可以向我解释我做错了什么,或者指出正确的方向吗?

1 个答案:

答案 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]

您将需要一种方法来在捕获端检查文件结尾。

相关问题