【问题标题】:Send input to python subprocess without waiting for result将输入发送到 python 子进程而不等待结果
【发布时间】:2018-09-26 05:10:16
【问题描述】:

我正在尝试为一段代码编写一些基本测试,该代码通常通过标准输入无休止地接受输入,直到给出特定的退出命令。

我想检查程序是否在收到一些输入字符串时崩溃(在处理一段时间后),但似乎无法弄清楚如何发送数据而不是等待输出不在乎。

我当前的代码是这样的(以cat作为程序示例):

myproc = subprocess.Popen(['cat'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

myproc.communicate(input=inputdata.encode("utf-8"))
time.sleep(0.1)

if myproc.poll() != None:
    print("not running")
else:
    print("still running")

如何修改它以允许程序继续进行轮询,而不是在communicate() 调用之后挂起?

【问题讨论】:

    标签: python subprocess popen


    【解决方案1】:

    您在这里使用了错误的工具,communicate 等待程序结束。您应该简单地提供子流程的标准输入:

    myproc = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE)
    myproc.stdin.write(inputdata.encode("utf-8"))
    
    time.sleep(0.1)
    
    if myproc.poll() != None:
        print("not running")
    else:
        print("still running")
    

    但请注意:您无法确定输出管道在子进程结束之前是否包含任何内容...

    【讨论】:

      【解决方案2】:

      您可以在Popen.communicate(input=None, timeout=None) 函数中设置超时。超时后,进程仍在运行,我认为但您必须对其进行测试,您仍然可以通过通信发送输入。

      来自文档:

      如果进程在 timeout 秒后没有终止,则会引发 TimeoutExpired 异常。捕获此异常并重试通信不会丢失任何输出。

      如果超时,子进程不会被杀死,所以为了 正确清理一个表现良好的应用程序应该杀死孩子 处理并结束通信:

      【讨论】:

        【解决方案3】:

        我想我明白你在这里想要什么。如果你知道一个现有的命令会导致你的程序崩溃,你可以使用subprocess.Popen.wait(),它仍然会阻塞,但它会返回一个输出消息的元组以及与之相关的错误,如果有的话。

        然后您可以记录错误并在 try 异常语句中捕获它。

        当我使用子流程时,这真的很有帮助: https://docs.python.org/3/library/asyncio-subprocess.html

        【讨论】:

          猜你喜欢
          • 2013-11-08
          • 2021-11-19
          • 1970-01-01
          • 1970-01-01
          • 2019-06-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多