首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >进程终止后Popen对象的返回码为None

进程终止后Popen对象的返回码为None
EN

Stack Overflow用户
提问于 2016-06-21 18:32:29
回答 2查看 9.8K关注 0票数 10

我正在使用Popen运行一个进程。我需要等待进程终止。我正在检查该进程是否已通过returncode终止。当returncode不同于None时,进程必须已经终止。问题是,当print_outputFalse时,returncode始终为None,即使进程已经结束运行(终止)。但是,当print_outputTrue时,情况并非如此。我使用以下代码来运行该进程:

代码语言:javascript
运行
复制
def run(command, print_output=True):
    # code mostly from: http://sharats.me/the-ever-useful-and-neat-subprocess-module.html
    from subprocess import Popen, PIPE
    from threading import Thread
    from queue import Queue, Empty
    from time import sleep

    io_q = Queue()

    def stream_watcher(identifier, stream):
        for line in stream:
            io_q.put((identifier, line))

        if not stream.closed:
            stream.close()

    with Popen(command, stdout=PIPE, stderr=PIPE, universal_newlines=True) as proc:
        if print_output:

            Thread(target=stream_watcher, name='stdout-watcher', args=('STDOUT', proc.stdout)).start()
            Thread(target=stream_watcher, name='stderr-watcher', args=('STDERR', proc.stderr)).start()

            def printer():
                while True:
                    try:
                        # Block for 1 second.
                        item = io_q.get(True, 1)
                    except Empty:
                        # No output in either streams for a second. Are we done?
                        if proc.poll() is not None:
                            break
                    else:
                        identifier, line = item
                        print(identifier + ':', line, end='')

            Thread(target=printer, name='printer').start()

        while proc.returncode is None:
            sleep(2)
            proc.poll()

        if not proc.returncode == 0:
            raise RuntimeError(
                'The process call "{}" returned with code {}. The return code is not 0, thus an error '
                'occurred.'.format(list(command), proc.returncode))

        return proc.stdout, proc.stderr

有什么可能导致这个问题的线索吗?

编辑:发现了一些非常奇怪的事情。我正在运行以下代码:

代码语言:javascript
运行
复制
run(my_command, True)
print('--------done--------')
run(my_command, False)
print('--------done--------')

即使执行了run(my_command, False),也不会打印'--------done--------'

EN

回答 2

Stack Overflow用户

发布于 2017-02-22 03:20:34

TL;DR

subprocess.Popen()之后添加popen.wait()

解释部分(某种意义上)

Python运行太快,子进程结束,但无法读取返回代码

(我真的不知道它为什么这样做。欢迎解释)

我为什么要使用这个:

命令执行和get 返回代码和输出(标准输出)

代码语言:javascript
运行
复制
def exec_cmd(cmd):
    pop = subprocess.Popen(shlex.split(cmd), stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
    pop.wait()
    return [pop.returncode, pop.communicate()[0]]

另外:请阅读popen page上的.wait警告

票数 18
EN

Stack Overflow用户

发布于 2016-06-21 21:55:35

我不确定为什么它不工作,但我认为这与没有关闭流有关。下面的代码可以工作:

代码语言:javascript
运行
复制
def run(command, print_output=True):
    from subprocess import Popen, PIPE, STDOUT
    from io import StringIO

    popen = Popen(command, stdout=PIPE, stderr=STDOUT, universal_newlines=True)
    out = StringIO()
    for line in popen.stdout:
        if print_output:
            print(line, end='')
        else:
            out.write(line)

    popen.stdout.close()
    return_code = popen.wait()

    if not return_code == 0:
        raise RuntimeError(
            'The process call "{}" returned with code {}. The return code is not 0, thus an error '
            'occurred.'.format(list(command), return_code))

    stdout_string = out.getvalue()
    out.close()

    return stdout_string
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37942022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档