我想在python应用程序中执行一个程序,它将在后台运行,但最终会出现在前台。
GUI用于与之交互,但控件是通过stdin和stdout上的控制台提供的。我希望能够使用我的应用程序的GUI来控制它,所以我的第一个想法是:
- 叉子
- 在父级中,dup2 stdin和stdout以便访问它们
- 处决孩子
这在python中容易实现吗?如何实现?有没有其他方法可以实现我想要的,那会是什么?
首先,python子流程模块是正确答案
作为子流程示例:
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.execute()使问题的主要目标变得毫无意义。无法访问孩子的stdout/stderr作为另一个问题目标
使用标准Python子流程模块相当容易
http://docs.python.org/py3k/library/subprocess.html
构建的结构并不复杂!
查看此示例
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,更改目录,打开一个文件并处理并关闭!