【问题标题】:Python: fork, pipe and execPython:fork、pipe 和 exec
【发布时间】:2012-03-01 22:37:57
【问题描述】:

我想在 python 应用程序中执行一个程序,它会在后台运行,但最终会到前台。

GUI 用于与之交互。但控制是通过标准输入和标准输出上的控制台提供的。我希望能够使用我的应用程序的 GUI 来控制它,所以我的第一个想法是:

  • 分叉
  • 在父级、dup2 标准输入和标准输出中,以便访问它们
  • 执行孩子

这在 python 中很容易实现吗?如何实现?有没有其他方法可以实现我想要的,那会是什么?

【问题讨论】:

  • 答案是“是”和“是”。你写的问题的那些答案似乎没有帮助。请更新您的问题以澄清您想知道的内容。

标签: python exec fork stdio dup


【解决方案1】:

首先,pythonsubprocess module 是正确答案。

作为子流程示例:

import subprocess
x = subprocess.check_output(["echo","one","two","three"])

x 将是输出(python3 字节类:x.decode('utf-8') 用于字符串)

请注意,这不会复制 stderr。如果您还需要 stderr,您可以执行以下操作:

x = subprocess.check_output(["bash","-c", 'echo foo; echo bar >&2'],stderr=subprocess.STDOUT)

当然,还有许多其他方法可以捕获标准错误,包括到不同的输出变量。

使用直接控制

但是,如果您正在做一些棘手的事情并且需要直接控制,请检查以下代码:

import os
rside, wside = os.pipe()
if not os.fork():
    # Child

    os.close(rside)
    # Make stdout go to parent
    os.dup2(wside, 1)
    # Make stderr go to parent
    os.dup2(wside, 2)
    # Optionally make stdin come from nowhere
    devnull = os.open("/dev/null", os.O_RDONLY)
    os.dup2(devnull, 0)
    # Execute the desired program
    os.execve("/bin/bash",["/bin/bash","-c","echo stdout; echo stderr >&2"],os.environ)
    print("Failed to exec program!")
    sys.exit(1)

# Parent
os.close(wside)
pyrside = os.fdopen(rside)

for line in pyrside:
   print("Child (stdout or stderr) said: <%s>"%line)

# Prevent zombies!  Reap the child after exit
pid, status = os.waitpid(-1, 0)
print("Child exited: pid %d returned %d"%(pid,status))

注意:@Beginner's answer 在几个方面存在缺陷:包含 os._exit(0) 会立即导致子进程退出,从而使其他一切变得毫无意义。没有 os.execve() 使问题的主要目标毫无意义。无法访问孩子的 stdout/stderr 作为另一个问题目标。

【讨论】:

    【解决方案2】:

    使用标准 Python 子进程模块相当容易:

    http://docs.python.org/py3k/library/subprocess.html

    【讨论】:

    【解决方案3】:

    构建起来并不复杂!

    检查这个例子

    if os.fork():
        os._exit(0)
        os.setsid()
        os.chdir("/")
        fd = os.open("/dev/null", os.O_RDWR)
        os.dup2(fd, 0)
        os.dup2(fd, 1)
        os.dup2(fd, 2)
    if fd 2:
        os.close(fd)
    

    这段python代码设置了一个id,改变了目录,打开了一个文件并处理并关闭了!

    【讨论】:

    • 这可能是我在 C 中的做法,但我希望 python 有一些模块可以帮助我以简单且可移植的方式实现这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 2014-06-09
    • 2018-05-25
    • 2016-01-12
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    相关资源
    最近更新 更多