Como posso matar todos os trabalhos interrompidos?

91

Quando tento sair do meu servidor Linux, recebo a mensagem:

Há trabalhos interrompidos.

: Existe um único comando para matá-los?

Zubair
fonte
Exemplos adicionais nas perguntas e respostas de perguntas e respostas na U&L: unix.stackexchange.com/questions/124428/…
slm
Eu tinha um problema oposto agora, ele não avisaria sobre trabalhos interrompidos quando eu saí do shell! Tive que colocar shopt -s checkjobsno meu .bashrc
Sam Watkins
1
Pressione Ctrl + D novamente, ele vai deixar você sair agora, matando os postos de trabalho no processo
Jens Timmerman

Respostas:

73

Para eliminar rapidamente todos os trabalhos interrompidos no bash, digite:

kill -9 `jobs -ps`

jobs -pslista os IDs do processo ( -p) dos -strabalhos interrompidos ( ).
kill -9 `jobs -ps`envia sinais SIGKILL para todos eles.

ooshro
fonte
22
-1 para "kill Jobs"
1
não funcionou quando o trabalho foi "sudo su". ou seja, sudo kill `jobs -p`não funcionou, mas digitar explicitamente o PID funcionou.
user13107
14
Por que isso é tão votado? Está errado. Se os processos forem interrompidos, um processo killcomo esse não fará nada, já que os processos são interrompidos, eles não processarão o SIGTERM (-15) que é enviado a eles por padrão.
SLM
6
kill -9 fará o truque.
horárioof 12/10
84

Tente digitar isso:

kill -9 $(jobs -p)
Dukevin
fonte
9
Isso deve ser feito, mas acho que ele deve enviar primeiro um SIGTERM (-15) antes de enviar um SIGKILL (-9). Então, talvez propor algo como "kill $ (jobs -p); durma 3s; kill -9 $ (jobs -p)" seria melhor. Ao enviar o SIGTERM primeiro, os trabalhos podem fazer uma saída limpa (liberando recursos alocados, etc.).
rems
3
Kevin Duke, sua resposta é a que funcionou para mim. Não pude votar porque não tenho 15 em reputação. kill -9 $ (empregos -p)
2
@rems Exceto como slm apontou, eles não receberão o SIGTERM porque estão parados.
Paul Gear
1
Não funciona no zsh. Devido ao zsh não ser compatível com POS IX com trabalhos .
precisa
Então, como lidar com o zsh?
fx-kirin 01/03
16

A resposta aceita mataria todos os trabalhos (o que é suficiente neste caso) e não apenas os interrompidos. Se você quiser matar apenas os Parados, execute:

kill $(jobs -l | grep Stopped | cut -d' ' -f3)
Kit Sunde
fonte
O grep / cut pode ser combinado em um comando awk: awk '/Stopped/{print $3}')
laebshade 20/10
2
o -sargumento sobre os filtros de resposta aceita apenas as que pararam
79E09796
12

A maneira mais fácil é realmente tentar imediatamente a saída imediatamente; bashvai entender isso como "matar todos os trabalhos interrompidos e sair".

geekosaur
fonte
4
Isso enviará um HUP que não necessariamente interrompe nenhum trabalho.
Stephen Niedzielski
7
for x in `jobs -p` ; do kill -9 $x ; done
monu
fonte
2
você pode adicionar formatação de código a essa linha para facilitar a leitura.
drcelus
Você pode dar uma olhada na sua formatação novamente - use quatro espaços no início da linha para marcar um bloco como código (em vez de usar backtick). No momento, não está claro se você está usando backticks no seu código ou está tentando exibir o código usando backticks.
22413 dunxd
A formatação está correta. temos que passar os trabalhos -p usando backticks, caso contrário ele não será considerado como um comando, e isso gerará um erro.
Segunda
5

Caso isso ajude outra pessoa - a maioria das pessoas está aqui porque teve alguns processos interrompidos que eles iniciaram, em segundo plano através do shell talvez. Eu precisava encontrar processos, como root, interrompidos por outros usuários, para os quais as variantes do jobscomando não funcionariam.

Um pouco de escavação man psme levou a isso:

ps -a -o pid,user,cmd,state | grep 'T$'

Explicação: o -asinalizador diz mostrar todos os processos e, em seguida, -ocontrola a saída, que informações serão mostradas sobre cada processo. Eu estou escolhendo pid, user, cmd(linha de comando), e state, o que é o estado do processo .

De man ps:

PROCESS STATE CODES
   Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the
   state of a process:
           D    uninterruptible sleep (usually IO)
           R    running or runnable (on run queue)
           S    interruptible sleep (waiting for an event to complete)
           T    stopped, either by a job control signal or because it is being traced
           W    paging (not valid since the 2.6.xx kernel)
           X    dead (should never be seen)
           Z    defunct ("zombie") process, terminated but not reaped by its parent

então, finalmente, eu dirijo o grep T$que diz, mostre-me todos os processos que têm T na última coluna.

E então eu tenho uma boa lista de todos os processos de diferentes usuários que estão no estado parado.

$ ps -a -o pid,user,cmd,state | grep 'T$'
  865 joson74+ python                      T
  885 joson74+ sh -c less                  T
  886 joson74+ less                        T
 1014 minames+ python3.4 -i /home/minames  T
 5352 MooKo    nano stdio.h                T
 7851 harry    tmux attach                 T
12083 harry    tmux attach                 T
13495 gorylla+ python3.4 -i /home/gorylla1 T
18009 conr1d   vim                         T
19664 enythin+ python                      T
24906 wardlist python                      T
hwjp
fonte
Para interromper os trabalhos anexados ao shell atual, jobs -psé mais simples que esta resposta. Dito isto, esta resposta não mostra apenas os trabalhos interrompidos Ctrl-Zno shell, mas todos os trabalhos interrompidos: outros shells, outros usuários , incluindo trabalhos sendo depurados (por exemplo, por gdb).
Stéphane Gourichon
Para mim, a melhor resposta, mas não exatamente funcionando. Eu tive que usar ps -el | grep Tpara encontrar os processos no estado 'T'.
dr0i 01/02
4

Se você deseja remover alguns trabalhos interrompidos, mas não todos, tente o seguinte:

Primeiro, listar trabalhos, você obterá algo como isto:

$ jobs -l

[2]   4813 Stopped                 ./parse < call.txt
[3]-  4819 Stopped                 ./parse < call.txt

enviar kill para um trabalho parado, ele não fará nada além de fila do que trazê-lo para o primeiro plano; ele terminará

$ fg %2
./parse < call.txt
Terminated

$ jobs -l
[3]-  4819 Stopped                 ./parse < call.txt
sergei
fonte
4

Normalmente, se você recebeu essa mensagem, precisa sair duas vezes. Por exemplo, primeiro, Ctrl+Dvocê recebe a mensagem de aviso para informá-lo sobre os trabalhos interrompidos, pressionando pela segunda vez, você será desconectado, eliminando os trabalhos. O mesmo se aplica aos comandos logoute exit.

Para matá-los manualmente, tente: kill $(jobs -p).


Se você não deseja matar tarefas do seu shell atual, é possível removê-las da tabela de tarefas ativas sem matar usando o disowncomando Por exemplo

$ sleep 1000 &
[1] 19404
$ jobs
[1]+  Running                 sleep 1000 &
$ disown

Os trabalhos interrompidos também podem ser determinados pelo estado do processo ( Tcaractere), o que significa que o processo foi interrompido por um sinal como SIGSTOP, SIGTSTPou outro (como SIGTTIN, ou SIGTTOU).

Caso jobsum comando incorporado do shell não esteja disponível, os processos interrompidos poderão ser listados pelo seguinte comando:

ps wuax | awk '$8 ~ "T"'

Para matar todos eles, você pode digitar basicamente:

kill -9 $(ps wuax | awk 'NR>1 && $8 ~ "T" {print $2}')

Aqui está um teste simples:

$ sleep 1000 &
[1] 2014
$ sleep 1000 &
[2] 2015
$ sleep 1000 &
[3] 2016
$ sleep 1000 &
[4] 2017
$ killall -STOP sleep
[1]   Stopped                 sleep 1000
[2]   Stopped                 sleep 1000
[3]   Stopped                 sleep 1000
[4]   Stopped                 sleep 1000
$ ps wuax | awk '$8 ~ "T"'
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
vagrant   2014  0.0  0.0   7228   832 pts/0    T    20:38   0:00 sleep 1000
vagrant   2015  0.0  0.0   7228   708 pts/0    T    20:38   0:00 sleep 1000
vagrant   2016  0.0  0.0   7228   760 pts/0    T    20:38   0:00 sleep 1000
vagrant   2017  0.0  0.0   7228   828 pts/0    T    20:38   0:00 sleep 1000
$ kill -9 $(awk 'NR>1 && $8 ~ "T" {print $2}' <(ps wuax))
$ jobs
[1]   Killed                  sleep 1000
[2]   Killed                  sleep 1000
[3]   Killed                  sleep 1000
[4]   Killed                  sleep 1000
kenorb
fonte