我正在编写一个将使用子进程的Python脚本。主要思想是拥有一个运行专门子脚本的父脚本,例如运行其他程序或自己做一些事情。父脚本和子进程之间存在管道。我通过定期发送一些字符并检查响应来使用它们来控制子进程是否仍在响应。问题是,当子进程在屏幕上打印任何内容(即写入stdout或stderr)时,管道被破坏,一切都崩溃了。所以我的主要问题是是否有可能阻止在子进程中写入std *,因此只有写入管道的合法响应才有可能?我已经尝试Stop a function from writing to stdout但没有任何成功。
欢迎使用父和子进程之间通信的其他想法(基于文件的管道除外)。但是,必须使用子流程。
答案 0 :(得分: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()
不够灵活(如果您需要同时监控多个子进程和/或某个子进程的stdin数据依赖于其输出以响应上一个命令),您可以直接与p.stdout
,p.stderr
,p.stdin
属性互动。在这种情况下,您可能需要构建自己的监控循环并使用p.poll()
和/或p.returncode
。也可以通过p.send_signal()
来实现对子流程的控制。
答案 1 :(得分:0)
您可以将函数传递给执行所请求程序之前执行的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脚本,那么当它们尝试写入已关闭的文件描述符时,它们可能会因异常而死亡。