Encerrar todos os processos em segundo plano

10

Eu tenho alguns processos em segundo plano Stopped .

kill $(jobs -p) e kill 'jobs -p' não têm efeito

kill %1 , kill %2 , etc. terminam com sucesso os processos individuais

Como posso matar todos os processos em segundo plano com um comando?

Além disso, por que os dois primeiros comandos não funcionam para mim?

Estou executando o Linux Mint 15, 64 bits

    
por user49888 12.04.2014 / 21:17

4 respostas

10

Quando estão a correr

Parece que você pode fazer isso com kill e a saída de jobs -p .

Exemplo

$ sleep 1000 &
[1] 21952
$ sleep 1000 &
[2] 21956
$ sleep 1000 &
[3] 21960

Agora tenho 3 trabalhos falsos em execução.

$ jobs
[1]   Running                 sleep 1000 &
[2]-  Running                 sleep 1000 &
[3]+  Running                 sleep 1000 &

Mate todos eles assim:

$ kill $(jobs -p)
[1]   Terminated              sleep 1000
[2]-  Terminated              sleep 1000
[3]+  Terminated              sleep 1000

Confirmando que todos eles desapareceram.

$ jobs
$

Quando eles estão parados

Se você tem trabalhos que estão parados, não está sendo executado, faça isso.

Exemplo

$ kill $(jobs -p)

$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Stopped                 sleep 1000
[3]   Stopped                 sleep 1000

OK, então isso não os matou, mas isso é porque o sinal de kill não pode ser manipulado pelo processo em si, está parado. Então diga ao SO para fazer a matança em seu lugar. Isso é o que é um -9 .

$ kill -9 $(jobs -p)
[1]+  Killed                  sleep 1000
[2]-  Killed                  sleep 1000
[3]   Killed                  sleep 1000

Isso é melhor.

$ jobs
$ 

Quando alguns estão em execução e alguns estão parados

Se você tiver uma mescla de processos em que alguns estão parados e alguns estão em execução, você pode fazer um kill primeiro seguido por um kill -9 .

$ kill $(jobs -p); sleep <time>; \
    kill -18 $(jobs -p); sleep <time>; kill -9 $(jobs -p)

Estendendo um pouco o tempo, se você precisar de mais para permitir que os processos parem antes.

Sinais

Nem um HUP (-1) nem um SIGTERM (-15) para matar serão bem-sucedidos. Mas por que? Isso é porque esses sinais são mais gentis no sentido de que eles estão dizendo ao aplicativo para finalizar a si mesmo. Mas como o aplicativo está em um estado parado, ele não pode processar esses sinais. Então você só é claro que é usar um SIGKILL (-9).

Você pode ver todos os sinais que kill fornece com kill -l .

$ kill -l | column -t
1)   SIGHUP       2)   SIGINT       3)   SIGQUIT      4)   SIGILL       5)   SIGTRAP
6)   SIGABRT      7)   SIGBUS       8)   SIGFPE       9)   SIGKILL      10)  SIGUSR1
11)  SIGSEGV      12)  SIGUSR2      13)  SIGPIPE      14)  SIGALRM      15)  SIGTERM
16)  SIGSTKFLT    17)  SIGCHLD      18)  SIGCONT      19)  SIGSTOP      20)  SIGTSTP
21)  SIGTTIN      22)  SIGTTOU      23)  SIGURG       24)  SIGXCPU      25)  SIGXFSZ
26)  SIGVTALRM    27)  SIGPROF      28)  SIGWINCH     29)  SIGIO        30)  SIGPWR
31)  SIGSYS       34)  SIGRTMIN     35)  SIGRTMIN+1   36)  SIGRTMIN+2   37)  SIGRTMIN+3
38)  SIGRTMIN+4   39)  SIGRTMIN+5   40)  SIGRTMIN+6   41)  SIGRTMIN+7   42)  SIGRTMIN+8
43)  SIGRTMIN+9   44)  SIGRTMIN+10  45)  SIGRTMIN+11  46)  SIGRTMIN+12  47)  SIGRTMIN+13
48)  SIGRTMIN+14  49)  SIGRTMIN+15  50)  SIGRTMAX-14  51)  SIGRTMAX-13  52)  SIGRTMAX-12
53)  SIGRTMAX-11  54)  SIGRTMAX-10  55)  SIGRTMAX-9   56)  SIGRTMAX-8   57)  SIGRTMAX-7
58)  SIGRTMAX-6   59)  SIGRTMAX-5   60)  SIGRTMAX-4   61)  SIGRTMAX-3   62)  SIGRTMAX-2
63)  SIGRTMAX-1   64)  SIGRTMAX

Se você quiser aprender ainda mais sobre os vários sinais, eu recomendo strongmente que você dê uma olhada na página de manual de sinais, man 7 signal .

    
por 12.04.2014 / 21:39
2

Você pode tentar isso.

for x in 'jobs -p'; do kill -9 $x; done

No entanto, se você quiser encerrar o processo, pode emitir o comando como

for x in 'jobs -p'; do kill -15 $x; done

Na página Wiki do comando Kill ,

Um processo pode receber um sinal SIGTERM de quatro maneiras (a identificação do processo é '1234' neste caso):

kill 1234
kill -s TERM 1234
kill -TERM 1234
kill -15 1234

O processo pode receber um sinal SIGKILL de três maneiras:

kill -s KILL 1234
kill -KILL 1234
kill -9 1234

Conforme explicado em esta resposta, essa é a diferença entre rescindir e kill .

O sinal de terminação, SIGTERM , é um sinal que pode ser interceptado em um programa. Muitas vezes, os processos que devem ser executados em segundo plano capturam esse sinal e iniciam um processo de desligamento, resultando em uma saída limpa. O sinal kill, SIGKILL , não pode ser interceptado. Quando isso é enviado para um processo, isso resultará em uma interrupção abrupta do programa.

Quando você desliga ou reinicializa seu computador, por exemplo, geralmente um SIGTERM é enviado para os processos em execução, permitindo que eles saiam de uma maneira limpa, se o suportarem. Então, após alguns segundos, um SIGKILL é enviado para os processos que ainda estão sendo executados para que os recursos em uso sejam liberados à força (por exemplo, arquivos em uso) e a seqüência de desligamento possa continuar (por exemplo, desmontando sistemas de arquivos).

    
por 12.04.2014 / 21:21
1

Ok, brincando com isso eu vejo que quando você mata um trabalho que está parado (onde a execução foi pausada mas não terminada), então ela não terminará até que seja colocada em primeiro plano. Os programas são normalmente interrompidos pressionando Ctrl - Z no terminal. A maioria dos terminais envia o SIGSTOP neste caso, mas é claro que existem outras maneiras de enviá-lo, como com kill -STOP ou kill -19 .

É um comportamento normal para o programa não terminar imediatamente, pois o programa deve estar rodando para processar o sinal padrão SIGTERM enviado por kill . Além disso, às vezes, depois que bash envia SIGTERM para um processo em segundo plano, ele acaba interrompido (embora o SIGTERM ainda esteja pendente).

A forma mais segura de concluir todos os trabalhos ( sem recurso de kill -9 ) é enviar primeiro SIGTERM com% normalkill, depois enviar SIGCONT a qualquer trabalhos restantes, por exemplo:

kill $(jobs -p)
kill -18 $(jobs -p)

O SIGCONT ( 18 é o número do sinal) trará todos os trabalhos interrompidos para o primeiro plano, para que possam processar SIGTERM como normalmente faria.

Se todos os programas não terminarem com isso, existem alguns outros sinais que você pode tentar que normalmente terminam o processo, antes de recorrer a kill -9 . O primeiro que eu recomendo é SIGHUP , já que muitos programas que normalmente bloqueiam os outros sinais de terminação respondem a SIGHUP . Isso geralmente é enviado quando um terminal de controle é fechado, em particular, quando uma sessão ssh com tty é concluída. Muitos programas interativos, como shells, não respondem a outros sinais de terminação, mas farão isso, já que seria um problema para eles permanecerem em execução após o término de uma sessão de ssh (ou após o fechamento de qualquer terminal de controle). Para tentar isso você pode assim

kill -1 $(jobs -p)
kill -18 $(jobs -p)

Novamente, é claro que você precisa ter certeza de que o programa não está parado para que ele possa processar o sinal. Outros sinais de finalização que você pode tentar são SIGINT ( kill -2 ) e SIGQUIT ( kill -3 ). Mas é claro que os benefícios de tentar o alcance total diminuem e podem levar a um inevitável SIGKILL (também conhecido como kill -9 ).

    
por 12.04.2014 / 22:03
0

Isso encerrará todos os trabalhos no seu shell atual, um por um:

while kill %; do :; done

Explicação: % refere-se ao último trabalho na lista, por isso, fará um loop até que kill retorne um valor diferente de zero, o que significaria que não há mais trabalhos para finalizar.

Outra abordagem poderia ser enviar primeiro SIGTERM , depois SIGCONT para que seus trabalhos possam continuar e a primeira coisa que eles farão é receber seu SIGTERM .

/bin/kill $(jobs -p) && /bin/kill -CONT $(jobs -p)

(por alguma razão o kill embutido é estranho, então usei um externo aqui).

    
por 12.04.2014 / 21:38