繁体   English   中英

如何将print和stdout重定向到管道并从父进程读取它?

[英]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中导入它,并直接从那里调用函数。

编辑:

您真正想要的是:

  • 用户给您一个命令(几乎可以是任何东西)
  • [您确认该命令是安全的]-不确定是否要执行此命令,但应该...
  • 您使外壳执行命令并获取其输出-您可能还希望阅读stderr并控制退出代码

你应该尝试像

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.

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