【问题标题】:Using subprocess wait() and poll()使用子进程 wait() 和 poll()
【发布时间】:2011-03-01 01:45:21
【问题描述】:

我正在尝试编写一个使用subprocess 模块的小应用程序。

我的程序调用了一个需要一些时间来处理的外部 Bash 命令。在此期间,我想向用户展示一系列这样的消息:

处理。请稍候...
输出是 foo()

如何使用Popen.wait()Popen.poll() 来做到这一点。我读过我需要使用Popen.returncode,但我不知道如何让它主动检查状态。

【问题讨论】:

    标签: python subprocess


    【解决方案1】:

    wait()(指定timeout)和poll() 如果进程尚未完成,则返回None,如果进程已经完成,则返回不同的东西(我考虑一个整数,退出代码,希望是 0)。

    编辑

    wait()poll() 具有不同的行为:

    • wait(不带超时参数)将阻塞并等待进程完成。
    • 带有 timeout 参数的wait 将等待timeout 秒以完成该过程。如果它没有完成,它将抛出TimeoutExpired 异常。如果您发现异常,欢迎您继续,或再次访问wait
    • poll 总是立即返回。它有效地等待超时为 0,捕获任何异常,并在进程尚未完成时返回 None
    • 使用waitpoll,如果进程已完成,将设置popen 对象的returncode(否则为None - 您可以像调用waitpoll 一样轻松检查) ,函数的返回值也将是进程的返回码。

    编辑>

    所以我认为你应该这样做:

    while myprocess.poll() is None:
        print("Still working...")
        # sleep a while
    

    请注意,如果 bash 脚本创建大量输出,您必须使用 communicate() 或类似的东西来防止 stdoutstderr 被填充。

    【讨论】:

    • 我正在使用通信()。但我不明白如何在进程执行时返回返回码。
    • 我通过这样做解决了这个问题:如果 process.poll() 是 None: print 'Working'
    • 如果 stdoutstderr 被填充是一个问题,和/或在运行时将该信息传递给用户,请执行 for line in myprocess.stdout: print(line)for line in myprocess.stderr: print(line, file=sys.stderr)(或类似的东西)一次循环。不过要小心,因为读取是阻塞的。
    • 据我所知,截至 16 年 5 月 31 日的编辑,此答案不再不正确。 (我仍然赞成 @onlyone 发现错误。)
    【解决方案2】:

    @extraneon 的回答有点倒退。如果进程完成,wait()poll() 都会返回进程的退出代码。如果进程仍在运行,poll() 方法将返回 Nonewait() 方法将阻塞直到进程退出:

    查看以下页面:https://docs.python.org/3.4/library/subprocess.html#popen-objects

    Popen.poll()

    检查子进程是否已终止。设置并返回返回码属性。

    Popen.wait()

    等待子进程终止。设置并返回返回码属性。

    【讨论】:

    • 任何第一次尝试这个Popen.poll() 的人都需要对使用“真实”值有点警惕:如果你这样做if popen.poll(): 并且你的子进程返回了 0,这将是False,即它看起来像子进程还没有完成。最好使用if popen.poll()!=None: 进行测试。
    猜你喜欢
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    相关资源
    最近更新 更多