
Estoy ejecutando 3 aplicaciones con el mismo nombre de archivo desde diferentes rutas:
$ ~/app1/main
$ ~/app2/main
$ ~/app3/main
Quiero crear un script bash que acepte el nombre completo de un archivo ejecutable y finalice esa aplicación.
$ ./my_killer.sh /home/me/app2/main
¿Cómo puedo hacer eso, particularmente cómo puedo eliminar una aplicación por su nombre completo?
Respuesta1
Si solo necesita soporte para Linux (que supongo que es el caso dado que su pregunta está etiquetada como Linux), puede utilizar los /proc/%d/exe
enlaces simbólicos.
A continuación se muestra un ejemplo de cómo podría verse un script.
#!/bin/bash
if [ "$#" != 1 ] || [ "$1" = "" ]
then
echo "Usage: $0 <full-exe-path>" 1>&2
exit 1
fi
shopt -s extglob
cd /proc
for PID in [1-9]*([0-9])
do
if [ "$(readlink "$PID"/exe)" = "$1" ]
then
kill "$PID"
fi
done
Una advertencia a tener en cuenta es que si el ID del proceso es un subproceso del núcleo o no es de su propiedad, readlink
fallará y "$(readlink "$PID"/exe)"
se evaluará como una cadena vacía. Para evitar intentar eliminar todos esos procesos, el script se negará a hacer nada si $1
es una cadena vacía.
Tenga en cuenta también que este script hace uso de extglob
lo que permite hacer coincidir directorios con [1-9]*([0-9])
lo que significa un carácter en el intervalo 1-9
seguido de cualquier número de caracteres en el intervalo 0-9
.
Respuesta2
Hago esto en una sola línea con ribetes (necesitas gawk
y xargs
):
$>ps -ax | grep "/app2/main" | grep -v "grep" | gawk '{print $1}' | xargs kill
¿que está sucediendo aquí?
ps -ax # — list all processes in extended format
grep "/app2/main" # — show only processes that contain "/app2/main"
grep -v "grep" # — sort out the previous grep process with the mentioned string
gawk '{print $1}' # — use gawk to pick only the first column (process id)
xargs kill # — use xargs to pass pid to kill as an argument
Esto envía efectivamente una señal de interrupción al proceso que necesita. Puede envolverlo en un script bash, si desea un comando corto con un argumento.