您应该能够执行此解决方法:
工作解决方案:关闭 gnome-terminal-server
正如@j-f-sebastian 在评论中所建议的那样,gnome-terminal
只需发送请求(到gnome-terminal-server)以启动一个新终端并立即退出——没有什么可以杀死进程已经死了(并且新创建的进程不是后代:新的bash 进程是gnome-terminal-server 的孩子,而不是 gnome-terminal)。
import subprocess
import os, signal
import time
p=subprocess.Popen(['gnome-terminal -e bash'], stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
print "this is going to be closed in 3 sec"
time.sleep(3)
# this line returns the list of bash instances pid as string
bash_pids = subprocess.check_output(["pidof", "bash"])
# I get the last instance opened
pid_to_kill = bash_pids.split(" ")[0]
os.kill(int(pid_to_kill), signal.SIGTERM)
我的解决方案是遵循这个逻辑:
- 运行 gnome-terminal
- 获取最新的bash实例打开的进程id
- 杀死这个进程ID
无效的解决方案
这些解决方案可能适用于更简单的情况:
解决方案 1
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,您可以参考signal documentation。例如
在 Windows 上,signal() 只能使用 SIGABRT、SIGFPE、SIGILL、SIGINT、SIGSEGV 或 SIGTERM 调用
对于 Unix,你有一个相当广泛的方法列表来调用。
要更好地了解os.kill,您可以参考its documentation。
解决方案 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)
您的进程似乎正在打开阻止父进程关闭的子进程。将session id 添加到您的父进程中,您应该能够修复它。
解决方案 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)
此解决方案需要psutil。
解决方案 4
根据askubuntu,似乎关闭 gnome 终端实例的最佳方法是执行 bash 命令,例如:
killall -s {signal} gnome-terminal
其中 {signal} 模拟 Alt + F4。
您可以尝试使用 [pexpect]:
p = pexpect.spawn(your_cmd_here)
p.send('^F4')