使用子流程和命令' gnome-terminal -e bash
'我可以根据需要打开一个gnome-terminal(并让它坚持下去)。这可以通过
p=subprocess.Popen(['gnome-terminal', '-e', 'bash'])
或
p=subprocess.Popen(['gnome-terminal -e bash'], shell=True)
但我无法使用p.terminate()
或p.kill()
关闭终端。根据我的理解,使用shell=True
时这有点棘手,但我不希望遇到问题。
答案 0 :(得分:2)
终止终端及其子终端(在同一进程组中):
#!/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)
--disable-factory
用于避免重新使用活动终端,以便我们可以通过subprocess
句柄os.setpgrp
将gnome-terminal
放入其自己的流程组中,以便os.killpg()
可用于向此群组发送信号答案 1 :(得分:1)
您应该能够解决这个问题:
工作解决方案:关闭gnome-terminal-server
正如@ j-f-sebastian在评论中所建议的那样,gnome-terminal
只是发送请求(到
gnome-terminal-server
)以启动一个新的终端并立即退出 - 没有什么可以杀死进程已经死了(新创建的进程不是后代:新的{{1} } process是bash
的孩子,而不是gnome-terminal-server
)。
gnome-terminal
我的解决方案遵循以下逻辑:
破碎的解决方案
这些解决方案可能适用于更简单的情况:
解决方案1
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)
为了选择合适的信号传递方法而不是 SIGKILL ,您可以参考signal documentation。 E.g。
在Windows上,只能使用SIGABRT,SIGFPE,SIGILL,SIGINT,SIGSEGV或SIGTERM调用signal()
对于Unix,你有一个非常广泛的方法列表来调用。
要更好地了解 os.kill ,您可以参考its documentation。
解决方案2
对Unix有用的另一种方法可能是:
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)
您的流程似乎正在打开子进程,阻止父进程关闭。将session id添加到父进程,您应该能够修复它。
解决方案3
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)
此解决方案需要psutil。
解决方案4
根据askubuntu,似乎关闭gnome终端实例的最佳方法是执行bash命令,如:
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)
其中{signal}模拟Alt + F4。
您可以尝试使用[ pexpect ]:
killall -s {signal} gnome-terminal