Terminar cada proceso en segundo plano

10

Tengo algunos Stoppedprocesos en segundo plano.

kill $(jobs -p)y kill `jobs -p`no tiene efecto

kill %1, kill %2etc. finalizan con éxito los procesos individuales

¿Cómo puedo matar cada proceso en segundo plano con un comando?

Además, ¿por qué los dos primeros comandos no funcionan para mí?

Estoy ejecutando Linux Mint 15, 64 bit

usuario49888
fuente

Respuestas:

10

Cuando estan corriendo

Parece que puedes hacer esto con killy la salida de jobs -p.

Ejemplo

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

Ahora tengo 3 trabajos falsos en ejecución.

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

Mátalos a todos así:

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

Confirmando que todos se han ido.

$ jobs
$

Cuando son detenidos

Si tiene trabajos que están detenidos, en lugar de ejecutarlos, haga esto.

Ejemplo

$ kill $(jobs -p)

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

OK, eso no los mató, pero eso se debe a que la señal de muerte no puede ser manejada por el proceso en sí, se detiene. Entonces dígale al sistema operativo que mate en su lugar. Para eso -9es a.

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

Eso es mejor.

$ jobs
$ 

Cuando algunos se están ejecutando y otros están detenidos

Si tiene una bolsa mixta de procesos donde algunos se detienen y otros se ejecutan, puede hacer un killprimero seguido de a kill -9.

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

Extienda un poco el tiempo si necesita más para permitir que los procesos se detengan primero.

Señales

Ni un HUP (-1) o un SIGTERM (-15) para matar tendrán éxito. ¿Pero por qué? Esto se debe a que estas señales son más amables en el sentido de que le están diciendo a la aplicación que finalice por sí misma. Pero dado que la aplicación está detenida, no puede procesar estas señales. Entonces, su único curso es usar un SIGKILL (-9).

Puede ver todas las señales que killproporciona 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

Si quieres aprender más acerca de las diversas señales que animo uno a echar un vistazo a la página de señales hombre, man 7 signal.

slm
fuente
¿Por qué tenemos un +símbolo para el primer proceso y un -símbolo para el segundo proceso y ningún símbolo en el tercero?
Ramesh
Obtuve los mismos resultados que tú. Sin embargo, quiero hacerlo en terminatelugar de hacerlo kill, ya que he leído que es más seguro. Lo intenté kill -15 $(jobs -p), pero eso no tuvo ningún efecto. Supuse que los procesos detenidos solo pueden ser eliminados, pero de nuevo kill %numbertermina los procesos detenidos (individuales).
user49888
@Ramesh The +y -son solo los últimos procesos que toqué cuando estaba configurando los ejemplos. Esto +significa que cualquier comando que no incluya explícitamente %#a actuará en ese comando. El guión ( -) es el segundo al último comando que toqué.
slm
@ user49888: kill -9 .. debería haber funcionado. ¿Cuáles son los procesos? ¿Son procesos difuntos o huérfanos?
slm
1
@ user49888: sí, si el proceso estaba en medio de algo, no se le da la oportunidad de realizar ninguna limpieza antes de finalizar.
slm
2

Puedes probar esto.

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

Sin embargo, si desea finalizar el proceso, puede emitir el comando como,

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

Desde la página de comando WikiKill ,

Se puede enviar una señal SIGTERM a un proceso de cuatro maneras (la ID del proceso es '1234' en este caso):

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

El proceso puede enviarse una señal SIGKILL de tres maneras:

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

Como se explica en esta respuesta, esta es la diferencia entre terminar y matar .

La señal de terminación, SIGTERM , es una señal que puede ser interceptada en un programa. A menudo, los procesos destinados a ejecutarse en segundo plano captarán esta señal e iniciarán un proceso de apagado, lo que dará como resultado una salida limpia. La señal de muerte, SIGKILL , no puede ser interceptada. Cuando esto se envía a un proceso, dará como resultado una finalización abrupta de ese programa.

Cuando apaga o reinicia su computadora, por ejemplo, generalmente se envía un SIGTERM a los procesos en ejecución, permitiéndoles primero salir de manera limpia si lo admiten. Luego, después de unos segundos, se envía un SIGKILL a los procesos que aún se están ejecutando para que los recursos en uso se liberen por la fuerza (por ejemplo, archivos en uso) y la secuencia de apagado pueda continuar (por ejemplo, desmontar los sistemas de archivos).

Ramesh
fuente
Esto hace killtodos los procesos en segundo plano. Sin embargo, ¿hay alguna forma de terminatehacerlo, ya que creo que es más seguro?
user49888
Si desea terminar, puede usar -15el comando kill.
Ramesh
-15No funcionará aquí tampoco. Vea mi A.
slm
@Ramesh: los últimos 2 párrafos no son correctos. No se envía una SIGTERM (no inicialmente). Se intenta detener los procesos primero a través de los scripts de detención / inicio del servicio. Si ese fuera el caso de que se enviara un 9 al proceso, entonces con los procesos detenidos como en el ejemplo del OP, kill -9en mi ejemplo no habría funcionado.
slm
1

Ok, jugando con esto veo que cuando matas un trabajo que se detiene (donde la ejecución se ha detenido pero no se ha terminado), entonces no terminará hasta que se ponga en primer plano. Los programas se detienen comúnmente presionando Ctrl- Zen el terminal. La mayoría de las terminales envían el SIGSTOPen este caso, pero, por supuesto, también hay otras formas de enviarlo, como con kill -STOPo kill -19.

Es normal que el programa no termine de inmediato, ya que el programa debe estar ejecutándose para procesar la SIGTERMseñal predeterminada enviada por kill. Además, a veces después de bashenviar SIGTERMa un proceso en segundo plano, de alguna manera termina detenido (aunque SIGTERMtodavía está pendiente).

La forma más segura de terminar todos los trabajos ( sin recurrir a ellos kill -9) es primero enviar SIGTERMcon normalidad kill, luego enviar SIGCONTa cualquier trabajo restante, por ejemplo:

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

El SIGCONT( 18es el número de señal) traerá los trabajos detenidos al primer plano para que puedan procesar elSIGTERM como lo harían normalmente.

Si todos los programas no terminan con esto, entonces hay algunas otras señales que puede probar que normalmente hacen que el proceso finalice, antes de recurrir kill -9. La primera que recomiendo es SIGHUPporque muchos programas que generalmente bloquean las otras señales de terminación responden SIGHUP. Esto generalmente se envía cuando se cierra un terminal de control, en particular se envía cuando finaliza una sshsesión tty. Muchos programas interactivos, como los shells, no responderán a otras señales de terminación, pero lo harán, ya que sería un problema para ellos seguir funcionando después de que sshfinalice una sesión (o después de que se cierre cualquier terminal de control). Para probar esto puedes hacerlo

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

Nuevamente, por supuesto, debe asegurarse de que el programa no se detenga para que pueda procesar la señal. Otras señales de terminación que puede probar son SIGINT( kill -2) y SIGQUIT( kill -3). Pero, por supuesto, los beneficios de probar el rango completo disminuyen y pueden conducir a un inevitable SIGKILL(aka kill -9).

Graeme
fuente
Si lo hace man signal, puede obtener el material de referencia para respaldar esto.
slm
Esta es una forma más suave de lo que sugiere mi A. Hay casos en los que me he encontrado en el pasado donde esto todavía no limpiará las cosas por completo, por lo que si está haciendo esto desde un script, el kill -9 ..método funcionará en la mayoría de los casos. Esto a veces dejará los procesos dando vueltas, por lo que fallará la mayor parte del tiempo. Es una compensación que tienes que decidir. Es mejor ser duro y matar todo, arriesgando datos / limpieza en lugar de tener una limpieza más suave, pero tener que hacer más análisis a medida que sus asesinatos se vuelven progresivamente más duros.
slm
@slm, debe evitar kill -9siempre que sea posible, ya que esto simplemente desconecta sin darle al programa la oportunidad de limpiar adecuadamente. Actualizaré con algunas alternativas.
Graeme
Como dije, su sabor es más suave que lo que sugerí, todo se reduce a lo que está tratando de hacer en lugar de estar dispuesto a tolerar desde una perspectiva de riesgo. He usado tu método tan bien como el mío. Ambos son IMO correctos. También a kill ..; sleep <time>; kill -18 ..; dormir <hora>; matar -9 ... . Basically working up to the -9`.
slm
@slm, kill -18definitivamente es algo que debería usarse, ya que es común haber detenido trabajos (y en algunos casos parece que de bashalguna manera deja de ejecutar trabajos antes de enviarlos SIGTERM). Como se agregó anteriormente, SIGHUPtambién vale la pena intentarlo, ya que muchos programas que no responden a los demás responderán a esto (pruébelo con un shell). Sin embargo, más allá de eso, sí, no vale la pena, ya SIGKILLque probablemente sea inevitable.
Graeme
0

Esto terminará todos los trabajos en su shell actual uno por uno:

while kill %; do :; done

Explicación: se %refiere al último trabajo de la lista, por lo que se repetirá hasta que killdevuelva un valor distinto de cero, lo que significaría que no hay más trabajos para finalizar.

Otro enfoque podría ser enviar primero SIGTERM, luego SIGCONTpara que sus trabajos puedan continuar y lo primero que harán es recibir el suyo SIGTERM.

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

(por alguna razón, el incorporado killes extraño, así que usé uno externo aquí).

dnt
fuente