为了账号安全,请及时绑定邮箱和手机立即绑定

Subprocess.Popen:将stdout和stderr克隆到终端和变量

Subprocess.Popen:将stdout和stderr克隆到终端和变量

撒科打诨 2019-07-27 10:54:32
Subprocess.Popen:将stdout和stderr克隆到终端和变量是否可以修改以下代码以从'stdout'和'stderr'打印输出:印在终端上(实时),最后存储在out和errs变量中?代码:#!/usr/bin/python3# -*- coding: utf-8 -*-import subprocessdef run_cmd(command, cwd=None):     p = subprocess.Popen(command, cwd=cwd, shell=False,                          stdout=subprocess.PIPE,                          stderr=subprocess.PIPE)     outs, errs = p.communicate()     rc = p.returncode     outs = outs.decode('utf-8')     errs = errs.decode('utf-8')     return (rc, (outs, errs))
查看完整描述

3 回答

?
繁花如伊

TA贡献2012条经验 获得超12个赞

要在单个线程中逐行捕获并同时显示子进程中的stdout和stderr,可以使用异步I / O:

#!/usr/bin/env python3import asyncioimport osimport sysfrom asyncio.subprocess import PIPE@asyncio.coroutinedef read_stream_and_display(stream, display):
    """Read from stream line by line until EOF, display, and capture the lines.

    """
    output = []
    while True:
        line = yield from stream.readline()
        if not line:
            break
        output.append(line)
        display(line) # assume it doesn't block
    return b''.join(output)@asyncio.coroutinedef read_and_display(*cmd):
    """Capture cmd's stdout, stderr while displaying them as they arrive
    (line by line).

    """
    # start process
    process = yield from asyncio.create_subprocess_exec(*cmd,
            stdout=PIPE, stderr=PIPE)

    # read child's stdout/stderr concurrently (capture and display)
    try:
        stdout, stderr = yield from asyncio.gather(
            read_stream_and_display(process.stdout, sys.stdout.buffer.write),
            read_stream_and_display(process.stderr, sys.stderr.buffer.write))
    except Exception:
        process.kill()
        raise
    finally:
        # wait for the process to exit
        rc = yield from process.wait()
    return rc, stdout, stderr# run the event loopif os.name == 'nt':
    loop = asyncio.ProactorEventLoop() # for subprocess' pipes on Windows
    asyncio.set_event_loop(loop)else:
    loop = asyncio.get_event_loop()rc, *output = loop.run_until_complete(read_and_display(*cmd))loop.close()


查看完整回答
反对 回复 2019-07-27
  • 3 回答
  • 0 关注
  • 1354 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信