Inicié una aplicación que no se ejecuta, pero no puedo eliminarla porque todavía se está ejecutando. Puedo imprimir el PID, pero no finalizar el proceso al usarlo.
~ $ ps ax | grep snappr | awk '{print $1}'
70824
~ $ kill $(ps ax | grep snappr | awk '{print $1}')
-bash: kill: (70832) - No such process
Respuesta1
¿Notaste que obtuviste dos PID diferentes en los dos intentos?
Considere esto: si escribe un comando como vi raven.txt
, ps ax
se mostrará una línea que muestra un comando de vi raven.txt
. Del mismo modo, si escribe un comando como grep snappr
, ps ax
se mostrará una línea que muestra un comando de grep snappr
. Y, si canaliza la salida de eso ps
a través de grep snappr
, grep
encontrará la líneaeso se esta describiendo a si mismo. Entonces, si escribes
$ ps ax | grep snappr | awk '{print $1}'
repetidamente, imprimirá un número diferente cada vez (porque está imprimiendo el PID de grep
y obtienes un grep
proceso nuevo y único cada vez que ejecutas el comando).
Finalmente, considere: el kill
comando no se puede ejecutar hasta que se conozcan sus argumentos. Para que se conozca su argumento $(ps ax | grep snappr | awk '{print $1}')
es necesario que el oleoducto esté terminado. Esto implica que el grep
debe haber terminado 1 . Por lo tanto, kill
se le proporciona el PID del grep
proceso, pero sólo después de que el grep
proceso ha finalizado, por lo que, naturalmente, informa "No existe tal proceso".
Quizás debería haber mencionado que no hay ningún snappr
proceso en ejecución. Si lo hubiera, su primer comando generaría dos números: el PID de snappr
y el PID de grep snappr
. Ahora, si snappr
se estuviera ejecutando, su comando podría comenzar a ejecutarse de forma semicorrecta, es decir, que hace lo que desea pero también muestra un mensaje de error. Si snappr
se ejecuta con PID 42097 y grep snappr
se ejecuta con PID 70848, entonces el kill
comando será kill 42097 70858
, que finalizará snappr
y recibirá un mensaje de error al intentar finalizar el grep
proceso que ya no existe.
Probablemente querrás mejorar esto. Mi forma favorita, que inventé hace 20 años, es cambiar a grep
, grep "[s]nappr"
que coincidirá snappr
pero no coincidirá consigo mismo. Otro enfoque es utilizar pgrep
en lugar de ps | grep
.
1 Alternativamente, awk
podría finalizar si grep
simplemente cerrara su salida estándar. Este sería un comportamiento muy inusual para un programa *nix.
Respuesta2
Respuesta más corta
No saltes a través de los aros de Bash para matar snappr
, ps
pasas grep
y luego pasas awk
así. En su lugar, intenta matarlo así usandopkill
; sin complicaciones ni complicaciones y se orienta según el nombre del proceso listo para usar:
sudo pkill snappr
Respuesta más larga
No muy claro cómopargoopera a nivel de proceso del sistema, pero el problema podría ser que solo esté obteniendo la ID del proceso secundario en lugar de la ID del proceso principal.
De hecho, creo que el método que está utilizando para obtener una ID de proceso ( ps ax | grep snappr | awk '{print $1}'
) devolvería una lista completa de ID de procesos conectados, snappr
independientemente de si es principal o secundario. Así que usando esopodríaElimine un ID de proceso que sea solo un ID de proceso secundario, pero el ID principal aún estaría activo y podría "generar" otro proceso secundario para compensar.
Entonces, tal vez pueda hacer algo como esto para obtener la ID principal definitiva de cualquier ID de proceso que le proporcione y actuar en consecuencia; prueba simple de concepto de cómo funciona:
ps -p [process ID] -o ppid=
Ejecutar ese comando simple en Bash le dará el ID del proceso principal del ID del proceso secundario que ingresó [process ID]
. Entonces, si el ID secundario 4567
tiene un ID de proceso principal, 123
entonces el comando sería:
ps -p 4567 -o ppid=
Y eso volvería, 123
.
Dicho esto, esta podría ser una forma peligrosa de lidiar con un proceso perdido, ya que si su script toma el ID del proceso padre real de snapper
, entonces el padre de ese ID de proceso podría ser realmente su propio shell Bash. Por lo tanto, es posible que, sin darte cuenta, simplemente elimines tu shell Bash en lugar de snapper
sacarte del sistema mientras dejas snapper
el proceso en ejecución.
Pero dicho todo esto, ¿por qué no hacer tu vida más fácil y simplemente correr?pkill
como esto:
sudo pkill snappr
Eso eliminará todos los procesos conectados snappr
sin ningún malabarismo sofisticado con la línea de comandos.