如何判断通过管道的数据何时结束

时间:2016-12-06 16:55:16

标签: python linux pipe

在我的python程序中,我有两个subprocesses通过pipe互连,一个连接到stdin,另一个连接到stdout。我的问题是,当数据流结束时,子进程会挂起,直到我按下ctrl+c。它看起来像子过程被打开我的管道。如果我能告诉流经管道的数据何时可以手动关闭它。

def write(tag_name):
    p_r, p_w = os.pipe()
    pv = subprocess.Popen('pv', stdin=None, stdout=p_w)
    dd = subprocess.Popen('dd bs=64k of=/dev/nst0'.split(), stdin=p_r, stdout=None)
    dd.wait()

2 个答案:

答案 0 :(得分:2)

只是不要使用os.pipe(),您可以将子流程stdout直接传递给其他流程stdin,如下所示:

def write(tag_name):
    pv = subprocess.Popen('pv', stdin=None, stdout=subprocess.PIPE)
    dd = subprocess.Popen('dd bs=64k of=/dev/nst0'.split(), stdin=pv.stdout, stdout=None)
    dd.wait()

当第一个命令结束时,管道被破坏(而不是需要手动关闭的os.pipe()),因此它也会结束第二个命令并且脚本可以继续/结束。

我已经测试了一个简单的管道命令,并且os.pipe()它会在您描述的结尾处阻塞,但在第一个进程以我的修改结束时退出。

答案 1 :(得分:0)

这里需要一个非阻塞解决方案。 看看我的解决方案:https://github.com/vesellov/bitdust.devel/blob/master/system/nonblocking.py

你可以这样调用它(没有测试代码):

import nonblocking, time
p = nonblocking.Popen('pv'.split(), shell=True, )
p.make_nonblocking()
while 1:
    if p.state() == nonblocking.PIPE_CLOSED:
        # pipe closed, stop
        return break
    if p.state() == nonblocking.PIPE_READY2READ:
        newchunk = p.recv(1024)
        if newchunk == '':
            # EOF reached, stop
            break
        # do something with the data here
        # you can send it to second stream
    try:
       time.sleep(0.01)
    except KeyboardInterrup:
       break

所以当你调用dd.wait()时它会阻塞,这就是你的Ctrl-C无法正常工作的原因。你需要手动处理这个问题....非阻塞流媒体在Python中不是一个简单的故事。退房Twisted project,你可以找到很多很酷的东西:-)