我的最终目标是让我的python脚本在 another 终端中启动一个子进程,它独立于父进程运行:
- 当父进程完成时,子进程应该继续。它不应该被杀死。
- 父进程应该能够等待子进程完成,或者只是继续自己的工作。
我用下面的脚本实现了这个目标。请注意,我选择启动的子进程是python3 child.py
,但它可以是其他任何东西(不一定是python进程)。还要注意,在本例中,我通过在最后添加.communicate()
来让父进程等待子进程。
# Script parent.py
# ================
import subprocess, shutil
if __name__ == '__main__':
print('Launch child process')
p = subprocess.Popen(
['x-terminal-emulator', '-e', 'python3', 'child.py'],
).communicate()
print('Child process finished')
exit(0)
然后启动父进程:
$ python3 parent.py
效果很好。父进程首先打印'Launch child process'
,然后子进程出现在另一个终端中。孩子做他的事情,然后关闭。* 关闭子进程 * 后,父进程打印'Child process finished'
。太好了!
不幸的是,x-terminal-emulator
只存在于Debian及其衍生产品上。我的目标是让这种方法在 * 大多数 * Linux系统上工作。
到目前为止,我能找到的最明智的方法是尝试一些默认的“终端模拟器”,它们存在于最常见的Linux发行版中。例如:
'gnome-terminal'
'konsole'
'xterm'
'urxvt'
'rxvt'
'termit'
'terminator'
$TERMINAL
(这是一个非标准变量)
我尝试使用'gnome-terminal'
开始,但它已经出错了:
# Script parent.py
# ================
import subprocess, shutil
if __name__ == '__main__':
print('Launch child process')
# For the 'gnome-terminal', the '-e' argument is deprecated.
# One should use the '--' argument instead.
p = subprocess.Popen(
['gnome-terminal', '--', 'python3', 'child.py'],
).communicate()
print('Child process finished')
exit(0)
子进程启动了,但是父进程并没有等待它完成--尽管我通过在Popen(..)
的末尾添加.communicate()
明确地指示它这样做。
换句话说,父进程在子进程实际完成之前立即打印'Child process finished'
。
问题1:
为什么这种方法适用于'x-terminal-emulator'
而不适用于'gnome-terminal'
?PS:我正在使用Ubuntu。
- 编辑:我找到了解决这个问题的方法。必须添加
--wait
标志来告诉gnome-terminal
在其子进程退出之前不要返回。
问题二:
如何让这种方法在 * 大多数 * Linux系统上工作?如果我尝试启动任何其他终端模拟器,如xterm
,konsole
,...我是否会遇到类似的问题?我现在不能测试,因为我现在只有Ubuntu。
1条答案
按热度按时间gopyfrb31#
我相信我现在有一个相当好的方法。我列出了Linux中最常见的终端模拟器,并循环查看系统中存在哪一个。然后在该终端中启动子进程。
终端之间有一些细微的差别。我已经在我的Ubuntu上安装了一些。这是我目前掌握的情况:
请让我知道,如果我忘记了其中一个“大”的,或者如果我犯了任何错误,在启动这些终端的一些。
如果您想测试这个脚本,只需将其复制粘贴到
parent.py
文件中。在同一个文件夹中还需要一个child.py
文件。child.py
文件可以是任何东西。请随意使用此示例代码:然后像这样运行父对象: