代码之家  ›  专栏  ›  技术社区  ›  Joozty

python子进程包返回损坏的管道

  •  1
  • Joozty  · 技术社区  · 6 年前

    我正在尝试做一个使用子流程包的非常简单的示例。python脚本应该打开一个新进程并运行 read 命令。 阅读 命令应该通过管道接收来自stdin的输入。每次我尝试使用 write() flush() 它说:

    Traceback (most recent call last):
      File "recorder.py", line 68, in <module>
        p.stdin.flush()
    BrokenPipeError: [Errno 32] Broken pipe
    

    我的python代码如下:

    import subprocess
    import time
    
    
    p = subprocess.Popen(
        [
            "read",
        ],
        stdout=subprocess.PIPE,
        stdin=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        shell=True,
        bufsize=1
    )
    
    for character in "This is the message!\n":
        p.stdin.write(character.encode("utf-8"))
        time.sleep(0.25)
        p.stdin.flush()
    
    assert p.returncode == 0
    

    注意:一个字符接一个字符发送(有睡眠超时)非常重要。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Ondrej K.    6 年前

    实际上,我无法复制您的结果*,在我的例子中,您的循环会在 assert 作为 p 还没有完成,也没有 returncode (或者更确切地说,它的价值仍然是 None 那时)插入 p.wait() 循环之后和循环之前 断言 会强迫我们在 已终止。

    现在,对于您看到的例外情况,它很可能表示您要执行的管道 flush() ON是关闭的。很可能是由于进程已终止。也许在你的例子中,它已经有了一个(非零) 返回码 还有哪些可以进一步帮助理解问题?**


    *我的系统 /bin/sh 被使用 subprocess.Popen() 具有 shell=True 实际上是 bash . 运行 ["/bin/dash", "-c", "read"] 大概是壳牌公司要求的 /bin/SH 在你的系统里,我的管道也坏了。


    **像这样的短跑似乎失败了:

    /bin/dash: 1: read: arg count

    并返回 2 .

    哪种方式更像是一个短促的问题:为什么打电话 /bin/dash -c "read" (从 python )失败。好像是那个破折号 read (与它的bash对应物不同)总是期望至少有一个变量名作为参数读入(替换 阅读 具有 read foo )


    我想这个关于python的问题刚刚成为关于假设和shell脚本可移植性的一个教训。:)