Encerre todos os processos em segundo plano

10

Eu tenho alguns Stoppedprocessos em segundo plano.

kill $(jobs -p)e kill `jobs -p`não tem efeito

kill %1, kill %2etc., finalize com êxito 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

user49888
fonte

Respostas:

10

Quando eles estão correndo

Parece que você pode fazer isso apenas com killa saída de jobs -p.

Exemplo

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

Agora eu 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 se foram.

$ jobs
$

Quando eles estão parados

Se você tiver trabalhos que estão parados, não executando, faça isso.

Exemplo

$ kill $(jobs -p)

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

OK, para que não os matasse, mas é porque o sinal de matança não pode ser tratado pelo próprio processo, ele parou. Então, diga ao sistema operacional para matar. É para isso que -9serve.

$ 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 outros estão parados

Se você tiver um conjunto misto de processos em que alguns são interrompidos e outros estão em execução, você pode fazer o killprimeiro, seguido de a kill -9.

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

Estendendo o tempo levemente, se você precisar de mais para permitir que os processos parem primeiro.

Signals

Nem um HUP (-1) nem um SIGTERM (-15) para matar terão êxito. Mas por que? Isso ocorre porque esses sinais são mais gentis no sentido de que eles estão dizendo para o aplicativo se encerrar. Mas, como o aplicativo está parado, não pode processar esses sinais. Então, seu único curso é usar um SIGKILL (-9).

Você pode ver todos os sinais killfornecidos 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 que você dê uma olhada na página de manual de sinais man 7 signal,.

slm
fonte
por que temos +símbolo para o primeiro processo e -símbolo para o segundo processo e nenhum símbolo para o terceiro?
Ramesh
Eu tenho os mesmos resultados que você. No entanto, eu quero, em terminatevez de kill, uma vez que li que é mais seguro. Eu tentei kill -15 $(jobs -p), mas isso não teve efeito. Imaginei que os processos interrompidos só podem ser eliminados, mas, novamente kill %number, encerram os processos interrompidos (individuais).
user49888
@Ramesh Os +e -são apenas os últimos processos que toquei quando estava configurando os exemplos. O +meio que qualquer comando que não inclua explicitamente a %#atuará nesse comando. O dash ( -) é o penúltimo comando que toquei.
Slm
@ user49888 - o que kill -9 .. deveria ter funcionado. quais são os processos? Eles são processos extintos ou órfãos?
Slm
1
@ user49888 - sim, se o processo estava no meio de algo, não é dada a oportunidade de fazer qualquer limpeza antes de ser encerrada.
Slm
2

Você pode tentar isso.

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

No entanto, se você quiser finalizar o processo, poderá emitir o comando como,

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

Na página de comando do WikiKill ,

Um processo pode receber um sinal SIGTERM de quatro maneiras (neste caso, o ID do processo é '1234'):

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

Como explicado nesta resposta, esta é a diferença entre terminar e matar .

O sinal de terminação, SIGTERM , é um sinal que pode ser interceptado em um programa. Geralmente, 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 de morte, SIGKILL , não pode ser interceptado. Quando isso é enviado para um processo, resultará no encerramento abrupto desse programa.

Quando você desliga ou reinicia o computador, por exemplo, geralmente um SIGTERM é enviado aos processos em execução, permitindo que eles saiam de uma maneira limpa, se eles suportarem. Depois de alguns segundos, um SIGKILL é enviado aos processos que ainda estão em execução para que os recursos em uso sejam liberados à força (por exemplo, arquivos em uso) e a sequência de desligamento possa continuar (por exemplo, desmontando sistemas de arquivos).

Ramesh
fonte
Isso faz killtodo processo em segundo plano. No entanto, existe alguma maneira para terminateeles, pois acredito que é mais seguro?
user49888
Se você deseja finalizar, você pode usar -15o comando kill.
Ramsh
-15aqui também não funcionará. Veja meu A.
slm
@Ramesh - os últimos 2 parágrafos não estão corretos. Um SIGTERM não é enviado (não inicialmente). Os processos tentam parar primeiro por meio dos scripts de parada / inicialização do serviço. Se esse fosse o caso em que um 9 fosse enviado ao processo, com os processos parados, como no exemplo do OP, kill -9no meu exemplo não teria funcionado.
slm
1

Ok, brincando com isso, vejo que quando você mata um trabalho que está parado (onde a execução foi pausada, mas não terminou), ele não será concluído até que seja trazido para o primeiro plano. Os programas geralmente são interrompidos pressionando Ctrl- Zno terminal. A maioria dos terminais envia o SIGSTOPneste caso, mas é claro que também existem outras maneiras de enviá-lo, como com kill -STOPou kill -19.

É um comportamento normal que o programa não termine imediatamente, pois o programa precisa estar em execução para processar o SIGTERMsinal padrão enviado por kill. Além disso, às vezes após o bashenvio SIGTERMpara um processo em segundo plano, ele acaba sendo interrompido (embora o SIGTERMprocesso ainda esteja pendente).

A maneira mais segura de concluir todos os trabalhos ( sem recorrer a kill -9) é primeiro enviar SIGTERMcom um normal kille depois enviar SIGCONTpara os 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 eles possam processar o SIGTERMque normalmente faria.

Se todos os programas não terminarem com isso, existem alguns outros sinais que você pode tentar que normalmente fazem o processo terminar, antes de recorrer kill -9. O primeiro que eu recomendo é SIGHUPque muitos programas que normalmente bloqueiam os outros sinais de terminação respondem SIGHUP. Isso geralmente é enviado quando um terminal de controle é fechado, em particular é enviado quando uma sshsessão ttytermina. Muitos programas interativos, como shells, não respondem a outros sinais de terminação, mas respondem a isso, pois seria um problema permanecerem em execução após o término de uma sshsessão (ou após o fechamento de qualquer terminal de controle). Para tentar isso, você pode

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

Novamente, é claro que você precisa garantir que o programa não esteja parado para que possa processar o sinal. Outros sinais de terminação que você pode tentar são SIGINT( kill -2) e SIGQUIT( kill -3). Mas é claro que os benefícios de experimentar a gama completa diminuem e podem levar a um inevitável SIGKILL(aka kill -9).

Graeme
fonte
Se você fizer um, man signalpode obter o material de referência para fazer o backup.
Slm
Esta é uma forma mais suave do que meu A sugere. Há casos em que eu me deparei no passado em que isso ainda não limpa completamente as coisas; portanto, se você estiver fazendo isso a partir de um script, o kill -9 ..método funcionará na maioria dos casos. Às vezes, isso deixa os processos suspensos, por isso falhará na maior parte do tempo. É uma troca que você tem que decidir. É melhor ter mão pesada e matar tudo, arriscando dados / limpeza versus fazer uma limpeza mais suave, mas ter que fazer mais análises à medida que suas mortes se tornam progressivamente mais duras.
Slm
@ slm, você deve evitar kill -9sempre que possível, pois isso apenas puxa o plugue sem dar ao programa a chance de limpar corretamente. Vou atualizar com algumas alternativas.
Graeme
Como eu disse, seu sabor é mais suave do que o sugerido, tudo se resume ao que você está tentando fazer x disposto a tolerar da perspectiva de risco. Eu usei o seu método, assim como o meu. Ambos estão corretos na IMO. Também um kill ..; sleep <time>; kill -18 ..; dormir <hora>; matar -9 ... . Basically working up to the -9`.
Slm
@ SLM, kill -18definitivamente é algo que deve ser usado, pois é comum interromper os trabalhos (e, em alguns casos, parece que, de bashalguma forma, interrompe a execução dos trabalhos antes do envio SIGTERM). Como foi adicionado acima, SIGHUPtambém vale a pena tentar, pois muitos programas que não respondem aos outros responderão a isso (tente com um shell). Além disso, porém, sim, não vale a pena, pois SIGKILLprovavelmente é inevitável.
Graeme
0

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

while kill %; do :; done

Explicação: %refere-se ao último trabalho na lista, portanto ele fará um loop até killretornar um valor diferente de zero, o que significaria que não há mais trabalhos a serem finalizados.

Outra abordagem pode ser o primeiro envio SIGTERM, SIGCONTpara que seus trabalhos possam continuar e a primeira coisa que eles farão é receber o seu SIGTERM.

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

(por algum motivo, o built-in killé estranho, então usei um externo aqui).

dnt
fonte