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

36

Eu escrevi um script bash que chama vários outros programas e executa vários comandos. Eu executo esse script no terminal. Agora eu quero matar o script.

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

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

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

becko
fonte
8
Nesses casos, eu tentoCtrl + z
kenn
E depois da Ctrl + zexecução:kill -9 $(pgrep -f your_script.sh)
Noam Manos

Respostas:

38

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

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

kill -PID

Onde PIDestá o ID do processo do script.

Exemplo:

Considere um script test.shque inicia alguns processos. Digamos que você o executou 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 SIGINTe, portanto, este comando é equivalente a pressionar CtrlCo terminal. Para enviar SIGKILL:

kill -KILL -17802

Você só precisa interromper o script se não conseguir abrir outro terminal. Se puder, use pgreppara encontrar o PID.

Um dos comandos que o script inicia pode estar interceptando SIGINT, e é provavelmente por isso que CtrlCé ineficaz. No entanto, SIGKILLnão pode ficar preso, e geralmente é uma opção de último recurso . Você pode tentar SIGTERM( -TERM) antes de ir para a matança. Nem SIGKILLou SIGTERMpode ser configurado como um atalho de teclado da maneira SIGINTé.

Tudo isso é discutível se o seu script não contém uma linha shebang. A partir desta resposta SO :

Normalmente, o shell pai adivinha que o script foi escrito para o mesmo shell (shells mínimos semelhantes a Bourne executam o script com / bin / sh, o bash o executa como um subprocesso do bash) ...

Por esse motivo, quando o script é executado, você não encontra um processo com o nome do script (ou um processo com o nome do script na linha de comando) e pgrepfalha.

Sempre use uma linha shebang.

muru
fonte
Existe uma combinação de teclado para SIGKILLou SIGTERM?
Becko
@becko Não, e você não pode configurar um: superuser.com/a/417991/334516
muru
pgrep test.shnão retorna o PID para mim. Tentei um simples test.sh: for i in {1..30}; do sleep 1 echo $i done enquanto test.shestiver em execução, executo pgrep test.shem outro terminal, mas nada é retornado. O que há de errado?
Becko
1
@ Becko como você executou o script? Também tente pgrep -f test.sh.
muru 4/09/14
pgrep -f test.shtambém não funciona. Eu corro o script com./test.sh
becko
6

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

 ps -A

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

 kill -9 PID_Number
Harris
fonte
1
Isso é muito complicado. O script gera vários outros programas, e esses programas também geram processos paralelos. É muito difícil acompanhar todos esses processos. Deve haver uma solução mais simples, algo análogo ao que acontece quando você fecha a janela do terminal.
Becko
Você pode tentar pkill -P $$
Harris
1

Como Harris disse, você pode executar, Kill -9 PID_Numbermas também pode instalar o pacote conhecido por htopter um navegador de processo interativo que facilita a localização de processos específicos. O htop também suporta processos de morte.

Bulbasaur privado de sono
fonte