Вы должны быть в состоянии сделать это временное решение:
- получить идентификатор процесса
- убить процесс
Рабочий раствор: Закрыть гном-терминал-сервер
Как было предложено @ jf-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)
Мое решение следовать этой логике:
- запустить гном-терминал
- получить последний Баш экземпляр открыт идентификатор процесса
- убить этот идентификатор процесса
Наружные решения
Эти решения могут работать в более простых случаях:
Решение 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, сигнал() может быть вызван только с 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, кажется, что лучший способ, чтобы закрыть экземпляр гном терминала будет выполнять команду Баш как:
killall -s {signal} gnome-terminal
где {сигнал} имитирует Alt + F4.
Вы можете попробовать сделать это с помощью [pexpect]:
p = pexpect.spawn(your_cmd_here)
p.send('^F4')
Есть ли способ обойти это без '--disable-factory'? Я пытаюсь сделать это, возможно, работать с xterm, у которого нет опции '--disable-factory'. – Shatnerz
@Shatnerz: Я не знаю, как работает 'xterm'. Вы можете задать отдельный вопрос о переполнении стека о случае xterm. – jfs