简体   繁体   English

Python子进程捕获stdout竞争条件

[英]Python subprocess capture stdout race condition

When starting a process with POpen I want to capture the stderr and stdout pipes. 使用POpen启动进程时,我想捕获stderr和stdout管道。 My code works but has a race condition between the process being executed and the stream being wrapped. 我的代码有效但在正在执行的进程和被包装的流之间存在竞争条件。 This manifests itself by some stdout bleed into the console before being wrapped when the scheduler returns to the Python program. 当调度程序返回到Python程序时,这会在一些stdout流入控制台之前表现出来。

# Start process.
proc = subprocess.Popen(cmd_args, env=context, cwd=cwd,
    stdout=subprocess.PIPE if capture_out else subprocess.DEVNULL,
    stderr=subprocess.PIPE if capture_err else subprocess.DEVNULL,
    stdin=None)

# Wrap streams.
out_stream = NonBlockingStreamReader(proc.stdout) if capture_out else None
err_stream = NonBlockingStreamReader(proc.stderr) if capture_err else None

How can I wrap the streams before passing them into subprocess.Popen ? 如何在将subprocess.Popen之前将其包装起来?

This manifests itself by some stdout bleed into the console before being wrapped when the scheduler returns to the Python program. 当调度程序返回到Python程序时,这会在一些stdout流入控制台之前表现出来。

There is no race. 没有比赛。

stdout is either PIPE or DEVNULL in your case. stdout在你的情况下是PIPEDEVNULL stdout is redirected even before cmd_args is executed (after the fork but before exec() is called). 即使执行cmd_args 之前 (在fork之后但在调用exec()之前exec() stdout也会被重定向。

If you see any output at all; 如果你看到任何输出; it means that cmd_args writes outside of stdout , stderr ie, it may write to the terminal directly. 这意味着cmd_argsstdoutstderr之外写入,即它可以直接写入终端。 See the first reason in Q: Why not just use a pipe (popen())? Q中看到第一个原因:为什么不使用管道(popen())?

You could use pty ( pexpect ), to capture such output, code example . 您可以使用ptypexpect )来捕获此类输出, 代码示例 There could be some issues if you want to provide multiple pseudo-ttys (to capture stdout/stderr separately) . 如果要提供多个伪ttys(分别捕获stdout / stderr),可能会出现一些问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM