Como matar um script em execução no terminal, sem fechar o terminal (Ctrl + C não funciona)?

30

Eu escrevi um script bash que chama vários outros programas e executa vários comandos. Eu corro este script do terminal. Agora eu quero matar o script.

Pressionar Ctrl + C às vezes não funciona, acho que às vezes o script está executando outro programa e, por alguma razão, o sinal de kill não funciona.

No entanto, se eu fechar a janela do terminal, ele mata o script.

Existe algo que eu posso fazer (uma combinação de teclado), que é análogo ao fechamento da janela do terminal, sem realmente fechar a janela do terminal (não quero perder o histórico de comandos, diretório atual, histórico de saída, etc.) ?

    
por becko 04.09.2014 / 17:49

3 respostas

33

Você tem poucas opções. Uma é parar o script ( Ctrl Z ), obter o PID do script e enviar SIGKILL para o grupo de processos.

Quando um comando é executado em um shell, o processo é iniciado e todos os seus filhos fazem parte do mesmo < em> grupo de processos (neste caso, o grupo de processos em primeiro plano). Para enviar um sinal para todos os processos desse grupo, envie-o para o líder do processo. Para o comando kill , o líder do processo é indicado:

kill -PID

Em que PID é o ID do processo do script.

Exemplo:

Considere um script test.sh que lança alguns processos. Digamos que você o tenha executado em um shell:

$ ./test.sh

Em outro terminal,

$ pgrep test.sh
17802
$ pstree -ps '!!'
pstree -ps 'pgrep test.sh'
init(1)───sshd(1211)───sshd(17312)───sshd(17372)───zsh(17788)───test.sh(17802)─┬─dd(17804)
                                                                               ├─sleep(17805)
                                                                               └─yes(17803)

Nesse caso, para enviar um sinal ao grupo de processos criado por test.sh , você faria:

kill -INT -17802

-INT é usado para enviar SIGINT e, portanto, esse comando equivale a pressionar Ctrl C no terminal. Para enviar SIGKILL :

kill -KILL -17802

Você só precisa parar o script se não conseguir abrir outro terminal. Se você puder, use pgrep para encontrar o PID.

Um dos comandos que o script inicia pode ser o trapping SIGINT , que provavelmente é porque o Ctrl C é ineficaz. No entanto, SIGKILL não pode ser interceptado e geralmente é uma opção último recurso . Você pode querer tentar SIGTERM ( -TERM ) antes de ir para o kill. Nem SIGKILL ou SIGTERM pode ser configurado como um atalho de teclado como SIGINT é.

Tudo isso é irrelevante se o seu script não contiver uma linha shebang. De esta resposta SO :

  

Normalmente, o shell pai adivinha que o script é escrito para o mesmo shell (shells minimalistas como o Bourne executam o script com / bin / sh, o bash o executa como um subprocesso bash) ...

Por causa disso, quando o script é executado, você não encontrará um processo com o mesmo nome do script (ou um processo com o nome do script na linha de comando) e pgrep falhará.

Sempre use uma linha de shebang.

    
por muru 04.09.2014 / 18:19
5

Se você conhece os processos associados ao script, você pode encontrar o PID usando

 ps -A

e, em seguida, use o número PID para eliminar os processos correspondentes usando

 kill -9 PID_Number
    
por Harris 04.09.2014 / 17:56
0

Como Harris disse que você poderia executar Kill -9 PID_Number , mas também poderia instalar o pacote conhecido como htop para ter um navegador de processo interativo que facilita muito a localização de processos específicos. O htop também suporta processos de eliminação.

    
por Sleep Deprived Bulbasaur 04.09.2014 / 18:05

Tags