Python 终止使用子进程打开的gnome终端
使用子流程和命令“Python 终止使用子进程打开的gnome终端,python,terminal,subprocess,Python,Terminal,Subprocess,使用子流程和命令“gnome-terminal-ebash”,我可以根据需要打开一个gnome终端(并让它保持不变)。这两种方法都可以完成 p=subprocess.Popen(['gnome-terminal', '-e', 'bash']) 或 但是我无法使用p.terminate()或p.kill()关闭终端。据我所知,在使用shell=True时,这有点棘手,但我没想到在其他情况下会遇到问题。您应该能够解决此问题: 获取进程id 终止进程 工作解决方案:关闭gnome终端服务器 正
gnome-terminal-ebash
”,我可以根据需要打开一个gnome终端(并让它保持不变)。这两种方法都可以完成
p=subprocess.Popen(['gnome-terminal', '-e', 'bash'])
或
但是我无法使用
p.terminate()
或p.kill()
关闭终端。据我所知,在使用shell=True
时,这有点棘手,但我没想到在其他情况下会遇到问题。您应该能够解决此问题:
- 获取进程id
- 终止进程
gnome终端服务器
)启动一个新终端并立即退出——没有什么可以杀死的进程已经死了(并且新创建的进程不是后代:新的bash
进程是gnome终端服务器
的子进程,而不是gnome终端
)
我的解决方案遵循以下逻辑:
- 运行gnome终端
- 获取最新的bash实例打开的进程id
- 终止此进程id
import subprocess
import os, signal
p=subprocess.Popen(['gnome-terminal -e bash'], shell=True)
p_pid = p.pid # get the process id
os.kill(p_pid, signal.SIGKILL)
为了选择合适的信号传递方法而不是SIGKILL,您可以参考。例如
在Windows上,只能使用SIGABRT、SIGFPE、SIGILL、SIGINT、SIGSEGV或SIGTERM调用signal()
对于Unix,您有一个相当广泛的方法列表可供调用
要更好地了解os.kill,请参考
解决方案2
对Unix有用的另一种方法可以是:
import subprocess
import os, signal
p=subprocess.Popen(['gnome-terminal -e bash'], stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
os.killpg(os.getpgid(p.pid), signal.SIGTERM)
似乎您的进程正在打开阻止父进程关闭的子进程。向父进程添加一个,您应该能够修复它
解决方案3
import subprocess, psutil
def kill(p_pid):
process = psutil.Process(p_pid)
for proc in process.get_children(recursive=True):
proc.kill()
process.kill()
p = subprocess.Popen(['gnome-terminal -e bash'], shell=True)
try:
p.wait(timeout=3)
except subprocess.TimeoutExpired:
kill(p.pid)
这个解决方案需要一个新的解决方案
解决方案4
根据,关闭gnome终端实例的最佳方法似乎是执行bash命令,如:
killall -s {signal} gnome-terminal
其中{signal}模拟Alt+F4
您可以尝试使用[pexpect]执行此操作:
p = pexpect.spawn(your_cmd_here)
p.send('^F4')
要终止终端及其子级(在同一进程组中),请执行以下操作:
用于避免重新使用活动终端,以便我们可以通过--disable factory
句柄杀死新创建的终端子进程
将os.setpgrp
放在自己的进程组中,以便可以使用gnome终端
向该组发送信号os.killpg()
gnome终端
。在我的系统上,gnome终端
是一个启动应用程序,它不等待实际的终端退出:它只发送请求(到gnome终端服务器
),启动一个新的终端并立即退出——没有什么可以阻止进程已经死亡(新创建的进程不是子进程:新的bash
进程是gnome终端服务器的子进程,而不是gnome终端的子进程)。有没有办法不用--禁用工厂
?我正在尝试让它可以选择性地与xterm一起工作,而xterm没有--禁用工厂
选项。@Shatnerz:我不知道xterm
是如何工作的。你可以专门询问一个关于xterm
案例的堆栈溢出问题。只是更新:--禁用工厂不再受支持,至少从3.28.2版开始。我仍然对这个问题的答案感兴趣,因为这个解决方案对我不起作用!@JamesPaulMason:答案中的代码在我的带有GNOME终端3.28.2的Ubuntu机器上运行。只是在两个不同的系统上进行了尝试。它在带有GNOME终端3.18.3 b的Ubuntu上运行ut不使用gnome终端3.28.2,使用VTE 0.52.2+GNUTLS_(ツ)_/¯
killall -s {signal} gnome-terminal
p = pexpect.spawn(your_cmd_here)
p.send('^F4')
#!/usr/bin/env python
import os
import signal
import subprocess
p = subprocess.Popen(['gnome-terminal', '--disable-factory', '-e', 'bash'],
preexec_fn=os.setpgrp)
# do something here...
os.killpg(p.pid, signal.SIGINT)