阻止写入标准输出

Posted

技术标签:

【中文标题】阻止写入标准输出【英文标题】:Blocking writing to stdout 【发布时间】:2012-05-25 09:53:09 【问题描述】:

我正在编写一个将使用子进程的 Python 脚本。主要思想是拥有一个运行专门的子脚本的父脚本,例如运行其他程序或自己做一些事情。父脚本和子进程之间有管道。我使用它们通过定期发送一些字符并检查响应来控制子进程是否仍在响应。问题是当子进程在屏幕上打印任何东西(即写入标准输出或标准错误)时,管道被破坏并且一切都崩溃了。所以我的主要问题是是否可以在子进程中阻止写入 std* ,所以只有写入管道的合法响应是可能的?我已经尝试过Stop a function from writing to stdout,但没有任何成功。

还欢迎其他关于父进程和子进程之间通信的想法(基于文件的管道除外)。但是,必须使用子流程。

【问题讨论】:

【参考方案1】:

我坚信,您不必仅仅接受“当子进程在屏幕上打印任何内容(即写入 stdout 或 stderr)时,管道会损坏,一切都会崩溃”。你可以解决这个问题。然后,您不需要“阻止”子进程写入标准流。

正确使用子进程模块的所有功能。首先,将subprocess.PIPE 连接到子流程的每个标准流:

p = subprocess.Popen(
        [executable, arg1, arg2],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)

运行子进程并通过这些管道与之交互:

stdout, stderr = p.communicate(stdin="command")

如果communicate()不够灵活(如果您需要同时监控多个子进程和/或某个子进程的标准输入数据依赖于其响应前一个命令的输出),您可以直接与p.stdoutp.stderrp.stdin 属性。在这种情况下,您可能必须构建自己的监控循环并使用p.poll() 和/或p.returncode。也可以通过p.send_signal()实现对子进程的控制。

【讨论】:

【参考方案2】:

您可以将一个函数传递给subprocess.Popen,该函数在执行请求的程序之前执行:

def close_std():
    os.close(0)
    os.close(1)
    os.close(2)

p = subprocess.Popen(cmd, preexec_fn=close_std)

注意使用低级os.close;关闭 sys.std* 只会在分叉的 Python 进程中生效。另外,请注意,如果您的底层程序是 Python 脚本,它们可能会在尝试写入已关闭的文件描述符时因异常而死。

【讨论】:

它们是 Python 脚本,并且完全按照您编写的方式发生。但仍然感谢您的想法和时间。 @user1192062:为什么不将子进程的stdoutstderr 连接到管道?

以上是关于阻止写入标准输出的主要内容,如果未能解决你的问题,请参考以下文章

将 CSV 写入标准输出或文件名

如何将 CSV 输出写入标准输出?

当父母和孩子都写入标准输出时,输出中没有交错

以二进制模式写入标准输出的最简单方法是啥?

如何在从我产生的工作中获取一行标准输出时阻止 bash

如何使用 Popen 同时写入标准输出和日志文件?