linux: matar tarea en segundo plano

194

¿Cómo elimino la última tarea de fondo generada en Linux?

Ejemplo:

doSomething
doAnotherThing
doB &
doC
doD
#kill doB
????
flybywire
fuente
18
¿Cómo puede esto no estar relacionado con la programación? ¿La programación de Bash no es programación?
flybywire
66
Esto está en la región de superposición entre SO y SU, pero creo que encaja mejor aquí en SO. Mi criterio para pensar de esta manera es que si @flybywire está haciendo esto en un script, es programación. Si solo quisiera hacerlo desde la línea de comando, diría que pertenece a SU.
Bill the Lizard
10
El scripting de Shell también está programando.
cletus

Respuestas:

234

Hay una variable especial para esto en bash:

kill $!

PS se expande al PID del último proceso ejecutado en segundo plano.

falstro
fuente
68
@ polm23; no, ^Zno hace trabajos en segundo plano, los detiene. Un subsiguiente bgrealiza el 'fondo' real (reanuda la ejecución en segundo plano), y después de eso $!funciona como se esperaba.
falstro
Suponiendo que ????representa uno o más comandos que se ejecutarán después de matar, si alguno de esos comandos se basa en el trabajo realizado por el proceso en segundo plano, tenga en cuenta las tareas de limpieza o finalización que el proceso en segundo plano podría realizar en un controlador de señal después recibiendo una señal (atrapable). Es mejor agregar un wait(seguido quizás por un synco incluso un sleep <n>) justo antes del primero de dichos comandos 'dependientes'.
ack
2
Para completar: como un solo% también se refiere al trabajo actual, puede eliminar el trabajo detenido (^ z) con "kill%". Lo uso casi siempre después de ^ z.
t3o
Esto solo funciona si tiene habilitado el control de trabajo, que solo está activado de forma predeterminada en shells interactivos (aunque dado que se refiere al uso de ctrl-z, supongo que también se refiere al uso de un shell interactivo), pero esto ha sido descrito en otras respuestas aquí, no estoy seguro de por qué esto es "para completar" :)
falstro
289

Puedes matar por número de trabajo. Cuando pones una tarea en segundo plano, verás algo como:

$ ./script &
[1] 35341

Ese [1]es el número de trabajo y puede ser referenciado como:

$ kill %1
$ kill %%  # Most recent background job

Para ver una lista de números de trabajo, use el jobscomando. Más de man bash:

Hay varias formas de referirse a un trabajo en el shell. El personaje %introduce un nombre de trabajo. El número de trabajo nse puede denominar como %n. También se puede hacer referencia a un trabajo utilizando un prefijo del nombre utilizado para iniciarlo o una subcadena que aparece en su línea de comando. Por ejemplo, se %cerefiere a un cetrabajo detenido . Si un prefijo coincide con más de un trabajo, bash informa un error. Usar %?ce, por otro lado, se refiere a cualquier trabajo que contenga la cadena ceen su línea de comando. Si la subcadena coincide con más de un trabajo, bash informa un error. Los símbolos %%y%+consulte la noción del shell del trabajo actual, que es el último trabajo detenido mientras estaba en primer plano o se inició en segundo plano. Se puede hacer referencia al trabajo anterior usando %-. En la salida correspondiente a los trabajos (p. Ej., La salida del comando de trabajos), el trabajo actual siempre se marca con a +, y el trabajo anterior con a -. Un solo %(sin especificación de trabajo acompañante) también se refiere al trabajo actual.

John Kugelman
fuente
Para el registro, creo que esto solo funciona si el control de trabajo está habilitado. Aunque creo que puede activarlo en scripts ( set -m), está destinado para uso interactivo. Ver stackoverflow.com/questions/690266/… también
falstro
9
Símbolos muy útiles, estos %1y %%, especialmente. Algunas cosas no mueren en Ctrl-C, por lo que debe Ctrl-Z y luego kill -9 %%. Un ejemplo donde lo encontré útil es: while true; do mplayer <some unstable online radio>; date >> restarts.log; done- Ctrl-C solo lo llevará a la siguiente iteración del ciclo. Antes tenía que hacer pso tal vez jobs -l, y luego volver a escribir el PID, lo cual es tedioso.
Tomasz Gandor
¿Hay uno para todos los trabajos?
CMCDragonkai
3
@TomaszGandor Por eso es posible que desee reemplazar while truecon while sleep 1. Esto le dará un breve retraso antes de reiniciar si puede vivir con eso, y si presiona ctrl-c dos veces, el segundo interrumpirá el sueño, finalizando con una salida distinta de cero y saliendo del bucle.
falstro
45

El siguiente comando le brinda una lista de todos los procesos en segundo plano en su sesión, junto con el pid. Luego puede usarlo para matar el proceso.

jobs -l

Ejemplo de uso:

$ sleep 300 &
$ jobs -l
[1]+ 31139 Running                 sleep 300 &
$ kill 31139
Dave Vogt
fuente
25

Esto debería matar todos los procesos en segundo plano:

jobs -p | xargs kill -9
Prabhu Are
fuente
1
Esto es lo que usaría antes, pero kill -9 %%está escribiendo menos :)
Tomasz Gandor
44
@TomaszGandor Eso matará solo el trabajo actual, es decir, el último trabajo detenido en primer plano o iniciado en segundo plano. El comando en la respuesta matará TODOS los trabajos.
bitek
44
no mates -9
lesmana
2
skill doB

skill es una versión del comando kill que le permite seleccionar uno o varios procesos en función de un criterio determinado.

gte525u
fuente
0

Necesitas su pid ... usa "ps -A" para encontrarlo.

jldupont
fuente
0

Esta es una respuesta fuera de tema, pero, para aquellos que estén interesados, puede ser valiosa.

Como en la respuesta de @John Kugelman,% está relacionado con la especificación del trabajo. ¿Cómo encontrar eso de manera eficiente? use el comando less's & pattern , parece que man usa menos buscapersonas (no está tan seguro), en man bash escriba &% luego escriba Enter solo mostrará líneas que contengan '%', para volver a mostrar todo, escriba &. luego Enter.

qeatzy
fuente
-3

Solo usa el comando killall:

killall taskname

Para obtener más información y opciones más avanzadas, escriba "man killall".

zakk
fuente
44
Creo que Killall es un poco agresivo cuando en realidad tienes fácil acceso al PID. Y también peligroso, especialmente si eres root
Dave Vogt el
3
No es muy útil, si fue necesario killall pythono killall java, mientras se tiene algo útil ejecutándose en otras partes del sistema.
Tomasz Gandor