¿Cómo puedo matar todos los trabajos detenidos?

91

Cuando intento salir de mi servidor Linux recibo el mensaje:

Hay trabajos detenidos.

: ¿Hay un solo comando para matar a estos?

Zubair
fuente
Ejemplos adicionales en las preguntas y respuestas de U&L: unix.stackexchange.com/questions/124428/…
slm
Tenía un problema opuesto ahora, ¡no advertiría sobre los trabajos detenidos cuando salga del shell! Tuve que poner shopt -s checkjobsmi .bashrc
Sam Watkins
1
presione ctrl + d nuevamente, le permitirá salir ahora, matando esos trabajos en el proceso
Jens Timmerman

Respuestas:

73

Para eliminar rápidamente todos los trabajos detenidos debajo de bash, ingrese:

kill -9 `jobs -ps`

jobs -psenumera los ID de proceso ( -p) de los -strabajos detenidos ( ).
kill -9 `jobs -ps`envía señales de SIGKILL a todos ellos.

ooshro
fuente
22
-1 para "kill Jobs"
1
no funcionó cuando el trabajo era "sudo su". es decir, no sudo kill `jobs -p`funcionó pero explícitamente escribiendo PID sí.
usuario13107
14
¿Por qué se vota tanto? Está incorrecto. Si los procesos se detienen, entonces algo killcomo esto no hará nada, ya que los procesos se detienen, no procesarán el SIGTERM (-15) que se les envía por defecto.
slm
66
kill -9 hará el truco.
timetofly
84

Intenta escribir esto:

kill -9 $(jobs -p)
dukevin
fuente
99
Eso debería hacerlo, pero creo que debería enviar primero un SIGTERM (-15) antes de enviar un SIGKILL (-9). Quizás proponer algo como "kill $ (jobs -p); sleep 3s; kill -9 $ (jobs -p)" sería mejor. Al enviar SIGTERM primero, los trabajos pueden realizar una salida limpia (liberar recursos asignados, etc.).
rems
3
Kevin Duke, tu respuesta es la que funcionó para mí. No pude votar porque no tengo 15 en reputación. kill -9 $ (jobs -p)
2
@rems Excepto que, como señaló SLM, no obtendrán la SIGTERM porque están detenidos.
Paul Gear
1
No funciona en zsh. Debido a que zsh no cumple con POS IX con los trabajos .
Max Coplan
Entonces, ¿cómo lidiar con zsh?
fx-kirin
16

La respuesta aceptada mataría todos los trabajos (que es suficiente en este caso) y no solo los que se detuvieron. Si quieres matar solo a los detenidos, ejecuta:

kill $(jobs -l | grep Stopped | cut -d' ' -f3)
Kit Sunde
fuente
grep / cut se puede combinar en un comando awk: awk '/Stopped/{print $3}')
laebshade
2
el -sargumento sobre la respuesta aceptada filtra solo a los detenidos
79E09796
12

La forma más fácil es en realidad volver a intentar la salida inmediatamente; bashtomará eso como "matar todos los trabajos detenidos y salir".

geekosaur
fuente
44
Eso enviará un HUP que no necesariamente detiene ningún trabajo.
Stephen Niedzielski
7
for x in `jobs -p` ; do kill -9 $x ; done
monumentos
fuente
2
puede agregar formato de código para esta línea para que sea más fácil de leer.
drcelus
¿Puede echar un vistazo a su formato nuevamente? Use cuatro espacios al comienzo de la línea para marcar un bloque como código (en lugar de usar la tecla de retroceso). En este momento no está claro si está utilizando backticks en su código o si está tratando de mostrar el código utilizando backticks.
dunxd
El formato está bien. tenemos que pasar los trabajos -p usando backticks, de lo contrario no se considerará como un comando, y arrojará un error.
monumentos
5

En caso de que esto ayude a alguien más, la mayoría de las personas están aquí porque tienen algunos procesos detenidos que comenzaron, tal vez en segundo plano a través del shell. Necesitaba encontrar procesos, como root, detenidos por otros usuarios, para los cuales las variantes en el jobscomando no funcionarían.

Un poco de investigación man psme llevó a esto:

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

Explicación: la -abandera dice mostrar todos los procesos, luego -ocontrola la salida, qué información se mostrará sobre cada proceso. Estoy eligiendo pid, user, cmd(la línea de comandos), y state, lo que es el estado del proceso .

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

así que finalmente lo canalizo a lo grep T$que dice, muéstrame todos los procesos que tienen T en la última columna.

Y luego tengo una buena lista de todos los procesos de diferentes usuarios que están en estado detenido.

$ 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
fuente
Para obtener trabajos detenidos conectados al shell actual, jobs -pses más simple que esta respuesta. Dicho esto, esta respuesta no muestra solo los trabajos detenidos a través Ctrl-Zde un shell, sino todos los trabajos detenidos: otros shells, otros usuarios , incluidos los trabajos que se están depurando (por ejemplo, por gdb).
Stéphane Gourichon
Para mí la mejor respuesta, pero no funciona exactamente. Tuve que usar ps -el | grep Tpara encontrar los procesos en el estado 'T'.
dr0i
4

Si desea eliminar algunos trabajos detenidos pero no todos, intente esto:

Primero, enumere los trabajos, obtendrá algo como esto:

$ jobs -l

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

enviar kill a un trabajo detenido, no hará más que hacer cola que traerlo en primer plano, terminará

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

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

Normalmente, si recibió ese mensaje, debe cerrar la sesión dos veces. Por ejemplo, primero Ctrl+Dle da el mensaje de advertencia para informarle sobre los trabajos detenidos, presionar por segunda vez lo desconectará y matará los trabajos. Esto mismo se aplica a las logouty exitlos comandos.

Para matarlos de forma manual, trate: kill $(jobs -p).


Si no desea eliminar trabajos de su shell actual, puede eliminarlos de la tabla de trabajos activos sin eliminarlos mediante el disowncomando. P.ej

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

Trabajos detenidos también se puede determinar por el estado del proceso ( Tcarácter) que significa que el proceso se detuvo por la señal tal como SIGSTOP, SIGTSTPu otro (como SIGTTIN, o SIGTTOU).

En caso de que jobsun comando integrado de shell no esté disponible, los procesos detenidos se pueden enumerar mediante el siguiente comando:

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

Para matarlos a todos, básicamente puedes escribir:

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

Aquí hay una prueba simple:

$ 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
fuente