[英]multiprocessing: How can I ʀᴇʟɪᴀʙʟʏ redirect stdout from a child process?
[英]How to redirect print and stdout to a pipe and read it from parent process?
如果可能的话,我不想使用subProcess.popen
。 我想要捕获由孩子启动的进程的标准输出的原因是,我需要将孩子的输出保存在变量中,以便稍后显示。 但是,我还没有找到在任何地方这样做的方法。 我还需要激活多个程序,而不必关闭正在运行的程序。 我还需要控制父进程的子进程。
我正在启动这样的子流程
listProgram = ["./perroquet.py"]
listOutput = ["","",""]
tubePerroquet = os.pipe()
pipeMain = os.pipe()
pipeAge = os.pipe()
pipeSavoir = os.pipe()
pid = os.fork()
process = 1
if pid == 0:
os.close(pipePerroquet[1])
os.dup2(pipePerroquet[0],0)
sys.stdout = os.fdopen(tubeMain[1], 'w')
os.execvp("./perroquet.py", listProgram)
现在,你可以看到我启动程序与os.execvp
和使用os.dup2()
重定向孩子的标准输出。 但是我不确定我在代码中所做的事情,并想知道使用os.dup2
重定向stdout的正确方法,然后能够在父进程中读取它。
谢谢您的帮助。
我不明白为什么您不想使用出色的子流程模块,该模块可以为您节省很多样板代码(以及尽可能多的错误可能性...)。 无论如何,我假设perroquet.py
是python脚本,而不是可执行程序。 Shell知道如何为脚本找到正确的解释器,但是exec
系列是需要真正的可执行程序的低级函数。
您至少应该有以下内容:
listProgram = [ "python", "./perroquet.py","",""]
...
os.execvp("python", listProgram)
但我宁愿使用:
prog = subprocess.Popen(("python", "./perroquet.py", "", ""), stdout = PIPE)
甚至您已经在python中导入它,并直接从那里调用函数。
编辑:
您真正想要的是:
你应该尝试像
while True:
cmd = raw_input("commande :") # input with Python 3
if cmd.strip().lower() == exit: break
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True)
out, err = proc.communicate()
code = proc.returncode
print("OUT", out, "ERR", err, "CODE", code)
这是绝对不安全的,因为此代码会像底层shell一样执行任何命令(包括rm -rf *
, rd /s/q .
,...),但是它为您提供输出,输出和返回代码该命令,并且可以使用它是一个循环。 唯一的限制是,当您为每个命令使用不同的外壳程序时,您将无法使用更改外壳程序环境的命令-它们将被执行,但无效。
如果您需要提取对环境的任何更改,这是一个解决方案
from subprocess import Popen, PIPE
import os
def execute_and_get_env(cmd, initial_env=None):
if initial_env is None:
initial_env = os.environ
r_fd, w_fd = os.pipe()
write_env = "; env >&{}".format(w_fd)
p = Popen(cmd + write_env, shell=True, env=initial_env, pass_fds=[w_fd], stdout=PIPE, stderr=PIPE)
output, error = p.communicate()
# this will cause problems if the environment gets very large as
# writing to the pipe will hang because it gets full and we only
# read from the pipe when the process is over
os.close(w_fd)
with open(r_fd) as f:
env = dict(line[:-1].split("=", 1) for line in f)
return output, error, env
export_cmd = "export my_var='hello world'"
echo_cmd = "echo $my_var"
out, err, env = execute_and_get_env(export_cmd)
out, err, env = execute_and_get_env(echo_cmd, env)
print(out)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.