Python:fork,pipe和exec

8
我想在Python应用程序中执行一个程序,它将在后台运行,但最终会进入前台。
使用GUI与之交互。但是控件是通过标准输入输出的控制台提供的。我希望能够使用我的应用程序的GUI来控制它,所以我的第一个想法是:
- Fork - 在父进程中,dup2 stdin和stdout以访问它们 - 执行子进程
这在Python中是否容易实现?有没有其他方法可以实现我想要的效果?

1
答案是“是”和“是”。你提出的问题的答案似乎不太有用。请更新你的问题以澄清你想知道什么。 - S.Lott
3个回答

6

首先,Python的subprocess模块是正确的答案。

例如,使用子进程:

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)

当然,还有许多其他捕获stderr的方法,包括将其保存到不同的输出变量中。

使用直接控制

然而,如果您正在进行一些棘手的操作并需要直接控制,则可以查看下面的代码:

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))

注意:@初学者的回答存在一些缺陷:包括os._exit(0),这会立即导致子进程退出,使其他所有操作都变得无意义。没有os.execve(),使得问题的主要目标无法实现。没有方法可以访问子进程的stdout/stderr,这也是另一个问题的目标。

5

当然,那我就这样做吧。我一直在寻找2.X模块,幸运的是它已经存在很长时间了(http://docs.python.org/library/subprocess.html)。 - Aki
接受的答案应该是 https://dev59.com/sWDVa4cB1Zd3GeqPbTxF#55346918 -- 仅仅提供 Python 文档的链接并不能增加足够的价值。 - Stabledog

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有一些模块可以帮助我简单地实现并且具有可移植性。 - Aki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接