Encuentra y elimina un proceso en una línea usando bash y regex

650

A menudo necesito matar un proceso durante la programación.

La forma en que lo hago ahora es:

[~]$ ps aux | grep 'python csp_build.py'
user    5124  1.0  0.3 214588 13852 pts/4    Sl+  11:19   0:00 python csp_build.py
user    5373  0.0  0.0   8096   960 pts/6    S+   11:20   0:00 grep python csp_build.py
[~]$ kill 5124

¿Cómo puedo extraer la identificación del proceso automáticamente y eliminarla en la misma línea?

Me gusta esto:

[~]$ ps aux | grep 'python csp_build.py' | kill <regex that returns the pid>
Orjanp
fuente
3
¡Créame! : 'D La primera respuesta que seleccionó es mucho más compleja que la solución que le dijo en su respuesta. Prefiero elegir tu camino.
Santosh Kumar
La mejor manera de verificar si el proceso existe: stackoverflow.com/questions/3043978/…
Trevor Boyd Smith

Respuestas:

1400

En bash, deberías poder hacer:

kill $(ps aux | grep '[p]ython csp_build.py' | awk '{print $2}')

Los detalles sobre su funcionamiento son los siguientes:

  • El pste da la lista de todos los procesos.
  • Los grepfiltros que se basan en su cadena de búsqueda [p]son un truco para evitar que retome el grepproceso en sí.
  • El awksolo le da el segundo campo de cada línea, que es el PID.
  • La $(x)construcción significa ejecutar, xluego tomar su salida y ponerla en la línea de comando. La salida de esa pstubería dentro de esa construcción anterior es la lista de ID de proceso, por lo que terminas con un comando como kill 1234 1122 7654.

Aquí hay una transcripción que lo muestra en acción:

pax> sleep 3600 &
[1] 2225
pax> sleep 3600 &
[2] 2226
pax> sleep 3600 &
[3] 2227
pax> sleep 3600 &
[4] 2228
pax> sleep 3600 &
[5] 2229
pax> kill $(ps aux | grep '[s]leep' | awk '{print $2}')
[5]+  Terminated              sleep 3600
[1]   Terminated              sleep 3600
[2]   Terminated              sleep 3600
[3]-  Terminated              sleep 3600
[4]+  Terminated              sleep 3600

y puedes verlo terminando todos los durmientes.


Explicando el grep '[p]ython csp_build.py'bit con un poco más de detalle:

Cuando lo sleep 3600 &sigue ps -ef | grep sleep, tiende a obtener dos procesos sleep, el sleep 3600y el grep sleep(porque ambos tienen sleepen ellos, eso no es ciencia espacial).

Sin embargo, ps -ef | grep '[s]leep'no creará un proceso con sleepél, sino que crea grep '[s]leep'y aquí está la parte difícil: grepno lo encuentra porque está buscando la expresión regular "cualquier carácter de la clase de caracteres [s](que es s) seguido por leep.

En otras palabras, está buscando sleeppero el proceso grep es el grep '[s]leep'que no tiene sleep.

Cuando alguien de aquí en SO me mostró esto, inmediatamente comencé a usarlo porque

  • es un proceso menos que agregar | grep -v grep; y
  • es elegante y astuto, una combinación rara :-)
paxdiablo
fuente
2
@paxdiablo, ¿puedes proporcionar un enlace para eso? Estoy desconcertado por qué funciona.
Glenn Jackman
58
Solo puede usar awk - ps aux | awk '/ [b] eam / {print $ 2}' , no se necesita grep
Yola
20
Mejor usar solo pgrep o pkill
NGix
2
Hay un pequeño problema: si el proceso ya ha finalizado, esta línea killse producirá con la salida estándarkill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Lionel Chan el
55
En lugar de grep '[p]ython csp_build.py'que también se puede utilizar: kill $(ps aux | grep 'python csp_build.py' | grep -v grep | awk '{print $2}'). grep -vdevuelve líneas no coincidentes.
usandfriends
138

si tienes pkill

pkill -f csp_build.py

Si solo desea grep contra el nombre del proceso (en lugar de la lista completa de argumentos), deje de lado -f.

ghostdog74
fuente
1
No pasó nada cuando probé esto.
Orjanp
8
use pgrep primero para verificar que ha asimilado el proceso correcto. luego use pkill nuevamente en el patrón correcto.
ghostdog74
18
+1. pgrepy pkilltrabaje siempre que tenga cuidado de especificar el proceso correctamente. Por defecto, solo se corresponde con el nombre del proceso , que casi con certeza es solo "python" en este caso. Use pgrep -f "python csp_build.py"para hacer coincidir el comando completo.
Sr.Spuratic
3
Es posible que deba forzar la muerte conpkill -9 -f csp_build.py
studgeek
1
Esta realmente debería ser la respuesta aceptada y mejor votada; estos otros con todo el asombro son innecesarios. Espero que la gente que encuentre esta página lea más allá de esa primera respuesta.
Jason C
89

Un trazador de líneas:

ps aux | grep -i csp_build | awk '{print $2}' | xargs sudo kill -9

  • Imprima la columna 2: awk '{print $2}'
  • sudo es opcional
  • Ejecutar kill -9 5124, kill -9 5373etc. (kill -15 es más elegante pero un poco más lento)

Prima:

También tengo 2 funciones de acceso directo definidas en mi .bash_profile (~ / .bash_profile es para osx, tienes que ver qué funciona para tu máquina * nix).

  1. p palabra clave
    • enumera todos los procesos P que contienen palabras clave
    • uso, p. ej .: p csp_build, p pythonetc.

código bash_profile:

# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}
  1. palabra clave ka
    • K ills A ll procesos que tienen esta palabra clave
    • uso, p. ej .: ka csp_build, ka pythonetc.
    • opcional por ejemplo, nivel de muertes: ka csp_build 15,ka python 9

código bash_profile:

# KILL ALL
function ka(){

    cnt=$( p $1 | wc -l)  # total count of processes found
    klevel=${2:-15}       # kill level, defaults to 15 if argument 2 is empty

    echo -e "\nSearching for '$1' -- Found" $cnt "Running Processes .. "
    p $1

    echo -e '\nTerminating' $cnt 'processes .. '

    ps aux  |  grep -i $1 |  grep -v grep   | awk '{print $2}' | xargs sudo kill -klevel
    echo -e "Done!\n"

    echo "Running search again:"
    p "$1"
    echo -e "\n"
}
a20
fuente
Recordatorio : no olvide reiniciar el shell bash (terminal) para cargar las nuevas funciones. O ejecutar source ~/.bash_profileen el shell actual para importar las nuevas funciones (esto es lo que prefiero).
a20
Como muchas de las otras respuestas aquí, esto sufre monumentalmente por el uso inútil degrep . Recuerde, cualquier cosa que parezca grep x | awk '{ y }'generalmente es mejor y, a menudo, más robusta si la reemplaza conawk '/x/ { y }'
tripleee
1
@tripleee el sitio web al que está enlazando le pertenece, ¿verdad? Me doy cuenta de que lo está vinculando en todas las secciones de comentarios. ¿Estás tratando de construir SEO?
a20
No, no me interesa el SEO. Espero crear conciencia.
tripleee
1
.. al vincular a su sitio web como si fuera un sitio de autoridad establecido. Agradable. Además, grep es más rápido .
a20
16
killall -r regexp

-r, --regexp

Interprete el patrón de nombre de proceso como una expresión regular extendida.

Miron Yanovskiy
fuente
15

Intenta usar

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill
Rahul
fuente
Tuve que cambiarlo un poco. Esto funcionó. Gracias. :) ps aux | grep 'python csp_build.py' | cabeza -1 | corte -d "" -f 5 | xargs kill
Orjanp
3
ps aux | grep 'python csp_build.py' | awk '{print $2}' | xargs killtrabajó para mi. gracias
Rasika Perera
Recuerde, niños, Awk puede hacer todo lo grepposible, y la mayor parte de manera simple y elegante. El caso trivial de grep x y | awk '{ z }'siempre está mejor escrito awk '/x/ { z }' y; vea también el uso inútil degrep .
tripleee
12

Puede usar solo pkill '^python*'para matar el proceso de expresiones regulares.

Si quieres ver lo que vas a matar o encontrar antes de matar, solo usa pgrep -l '^python*'where -l salidas también nombre del proceso. Si no quieres usar pkill, usa solo:

pgrep '^python*' | xargs kill

NGix
fuente
8

Use pgrep, disponible en muchas plataformas:

kill -9 `pgrep -f cps_build`

pgrep -f devolverá todos los PID con coincidencia "cps_build"

vr286
fuente
2
Si tienes pgrep, también tendrás pkill. Como siempre, no lo use akill -9 menos que sepa por qué kill -15(el valor predeterminado) o kill -2no funcionará.
tripleee
Esto parece una peor paráfrasis de la respuesta de @nathanael que omite la dirección errónea -9y utiliza la sintaxis de sustitución de comandos moderna adecuada. Vota eso en su lugar; aunque, por supuesto, la pkillrespuesta es mejor aún.
tripleee
@tripleee En este caso, matar -9 es exactamente lo que quiero: terminar con todos los delincuentes con prejuicios extremos. Además, he usado kill -9 durante muchos años sin problemas. En mi opinión, siempre habrá un campo de puristas frente a un campo de realistas de hacer las cosas, y yo pertenezco a este último (en este asunto).
a20
¿Te perdiste la parte de "a menos que sepas por qué"? Estoy a favor de hacer las cosas, pero esta es una de las formas comunes de dispararte en el pie hasta que entiendas lo que -9realmente significa.
tripleee
@tripleee hey tripleee, recientemente descubrí que tienes razón, kill -15 es una mejor opción porque le da a la aplicación la oportunidad de suicidarse con gracia. He cambiado mi código en consecuencia: stackoverflow.com/a/30486159/163382
a20
7

Esto devolverá solo el pid

pgrep -f 'process_name'

Entonces, para matar cualquier proceso en una línea:

kill -9 $(pgrep -f 'process_name')

o, si conoce el nombre exacto del proceso, también puede probar pidof:

kill -9 $(pidof 'process_name')

Pero, si no conoce el nombre exacto del proceso, pgrepsería mejor.

Si hay varios procesos ejecutándose con el mismo nombre, y desea eliminar el primero, entonces:

kill -9 $(pgrep -f 'process_name' | head -1)

También tenga en cuenta que, si le preocupa la mayúsculas y minúsculas, puede agregar la opción -i como en grep. Por ejemplo:

kill -9 $(pgrep -fi chrome)

Más información sobre señales y pgrep en man 7 signalo man signalyman pgrep

Rakib Fiha
fuente
5

puedes hacerlo con awk y backtics

ps auxf |grep 'python csp_build.py'|`awk '{ print "kill " $2 }'`

$ 2 en awk imprime la columna 2, y el backtics ejecuta la declaración que se imprime.

Pero una solución mucho más limpia sería que el proceso de Python almacene su ID de proceso en / var / run y luego simplemente puede leer ese archivo y matarlo.

Alexander Kjäll
fuente
¿No matarás tanto el proceso 5124 como el 5373 entonces? Supongo que esto no es un problema.
Orjanp
no debería ser un problema, pero siempre puede agregar otro grep para excluir el proceso grep: "grep -v grep" entre grep y awk
Alexander Kjäll
Probado con un comando ligeramente modificado. Pero no eliminó el proceso, solo imprimió kill <pid>. ps auxf | grep '[p] ython csp_build.py' | awk '{print "kill" $ 2}'
Orjanp
Solo es necesario intercambiar la declaración de impresión "kill" $ 2 con un sistema ("kill" $ 2). Entonces funciona. :)
Orjanp
5

Mi tarea fue matar todo lo que coincida con la expresión regular que se coloca en un directorio específico (después de las pruebas de selenio, no todo se detuvo). Esto funcionó para mí:

for i in `ps aux | egrep "firefox|chrome|selenium|opera"|grep "/home/dir1/dir2"|awk '{print $2}'|uniq`; do kill $i; done
Sarga
fuente
La -9opción de killes quizás demasiado agresiva. No les permite liberar sus recursos.
Birei
¡Agradable! ¡El único que considera el hecho de que puede haber más de un proceso de correspondencia! Una pequeña nota: quizás desee agregar un "grep -v grep" o algo así a las tuberías, para asegurarse de que el proceso grep en sí no aparezca en su lista de procesos.
Brad Parks
killacepta múltiples procesos, por lo que el bucle es básicamente inútil; y como se indica en otra parte de esta página, no debe usarlo a kill -9menos que sepa que el proceso no responderá solo kill.
tripleee
eliminar -9 no es gran cosa, ¿por qué rechazar? Será mejor que edites la respuesta.
Serge
5

Para matar el proceso por palabra clave midori, por ejemplo:

kill -SIGTERM $(pgrep -i midori)

l3v1ath4n
fuente
3

Un método que usa solo awk(y ps):

ps aux | awk '$11" "$12 == "python csp_build.py" { system("kill " $2) }'

Al usar la prueba de igualdad de cadenas, evito que este proceso coincida.

Schot
fuente
Por alguna razón, no tengo éxito en "python csp_build.py". Pero "python" solo golpea.
Orjanp
3
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15
Vijay
fuente
No se puede hacer +1 debido al límite diario, pero vale la pena usarlo pscon la -oopción.
P Shved
PD no me des mucho. [~] $ ps PID TTY TIME CMD 6365 pts / 6 00:00:00 ps 29112 pts / 6 00:00:00 bash
Orjanp
3

Dale -f a pkill

pkill -f /usr/local/bin/fritzcap.py

la ruta exacta del archivo .py es

# ps ax | grep fritzcap.py
 3076 pts/1    Sl     0:00 python -u /usr/local/bin/fritzcap.py -c -d -m
Robert1968
fuente
2

Empecé a usar algo como esto:

kill $(pgrep 'python csp_build.py')
Natanael
fuente
1

Matar nuestros propios procesos comenzados desde un PPID común es bastante frecuente, pkill asociado a la –Pbandera es un ganador para mí. Usando el ejemplo @ ghostdog74:

# sleep 30 &                                                                                                      
[1] 68849
# sleep 30 &
[2] 68879
# sleep 30 &
[3] 68897
# sleep 30 &
[4] 68900
# pkill -P $$                                                                                                         
[1]   Terminated              sleep 30
[2]   Terminated              sleep 30
[3]-  Terminated              sleep 30
[4]+  Terminated              sleep 30
Juan Diego Godoy Robles
fuente
1

No necesita el cambio de usuario para ps.

kill `ps ax | grep 'python csp_build.py' | awk '{print $1}'`
Alex V
fuente
1

En algunos casos, me gustaría matar procesos simultáneamente de esta manera:

➜ ~ dormir 1000 y
[1] 25410
➜ ~ dormir 1000 y
[2] 25415
➜ ~ dormir 1000 y
[3] 25421
➜ ~ pidof dormir
25421 25415 25410
➜ ~ kill `pidof sleep`
[2] - 25415 sueño terminado 1000                                                             
[1] - 25410 sueño terminado 1000
[3] + 25421 sueño terminado 1000

Pero, creo que es un poco inapropiado en su caso (puede estar ejecutando python a, python b, python x ... en segundo plano).

kashu.org
fuente
1

Si pkill -f csp_build.pyno elimina el proceso, puede agregarlo -9para enviar una señal de interrupción que no se ignorará. es decirpkill -9 -f csp_build.py

yosemite_k
fuente
1

La solución sería filtrar los procesos con un patrón exacto, analizar el pid y construir una lista de argumentos para ejecutar procesos de eliminación:

ps -ef  | grep -e <serviceNameA> -e <serviceNameB> -e <serviceNameC> |
awk '{print $2}' | xargs sudo kill -9

Explicación de la documentación:

La utilidad ps muestra una línea de encabezado, seguida de líneas que contienen información sobre todos sus procesos que tienen terminales de control.

-e Mostrar información sobre los procesos de otros usuarios, incluidos aquellos

-f Muestra el uid, pid, padre pid, uso reciente de CPU, inicio de proceso

La utilidad grep busca cualquier archivo de entrada dado, seleccionando líneas que

-e patrón, --regexp = patrón Especifique un patrón utilizado durante la búsqueda de la entrada: se selecciona una línea de entrada si coincide con alguno de los patrones especificados. Esta opción es más útil cuando se usan múltiples opciones -e para especificar múltiples patrones, o cuando un patrón comienza con un guión (`- ').

xargs : construye listas de argumentos y ejecuta la utilidad

kill - termina o señala un proceso

señal número 9 - KILL (muerte no capturable, no ignorable)

Ejemplo :

ps -ef  | grep -e node -e loggerUploadService.sh - -e applicationService.js |
awk '{print $2}' | xargs sudo kill -9
avivamg
fuente
0

Lo uso para matar a Firefox cuando se está bloqueando el script y el ataque de la CPU :) Reemplace 'Firefox' con la aplicación que desea morir. Estoy en el shell Bash: OS X 10.9.3 Darwin.

kill -Hup $(ps ux | grep Firefox | awk 'NR == 1 {next} {print $2}' | uniq | sort)

mrhassell
fuente
Sustitución grep Firefox | awk 'NR == 1 { next } ...'con awk 'NR == 1 || $11 !~ /Firefox/ { next } ...'no sólo ahorra un proceso, sino que también mejora la precisión. Tampoco es difícil deshacerse de sort | uniqAwk puro ( uniq | sortaunque, por supuesto, es simplemente incorrecto: perderá cualquier duplicado que no sea adyacente y ocultará el error al ordenar innecesariamente la salida de uniq).
tripleee
0

Yo uso gkill processname, donde gkill es el siguiente script:

cnt=`ps aux|grep $1| grep -v "grep" -c`
if [ "$cnt" -gt 0 ]
then
    echo "Found $cnt processes - killing them"
    ps aux|grep $1| grep -v "grep"| awk '{print $2}'| xargs kill
else
    echo "No processes found"
fi

NOTA: NO matará los procesos que tienen "grep" en sus líneas de comando.

Kostyantyn
fuente
1
Al igual que las muchas, muchas otras reinvenciones del cobertizo de yak, esto está plagado de un uso inútil degrep y otros antipatterns comunes de script de shell.
tripleee
-1

El siguiente comando será útil:

kill $(ps -elf | grep <process_regex>| awk {'print $4'})

p.ej., ps -elf | grep top

    0 T ubuntu    6558  6535  0  80   0 -  4001 signal 11:32 pts/1    00:00:00 top
    0 S ubuntu    6562  6535  0  80   0 -  2939 pipe_w 11:33 pts/1    00:00:00 grep --color=auto top

kill -$(ps -elf | grep top| awk {'print $4'})

    -bash: kill: (6572) - No such process
    [1]+  Killed                  top

Si el proceso todavía está atascado, use la extensión "-9" para hardkill, de la siguiente manera:

kill -9 $(ps -elf | grep top| awk {'print $4'})

Espero que ayude...!

Akshay Shah
fuente
-1

Encuentra y elimina todos los procesos en una línea en bash.

kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})
  • ps -ef | grep '<exe_name>'- Da la lista de detalles del proceso en ejecución (uname, pid, etc.) que coincide con el patrón. La lista de salida también incluye este grepcomando que lo busca. Ahora para matar necesitamos ignorar este grepproceso de comando.
  • ps -ef | grep '<exec_name>' | grep -v 'grep'- Agregar otro grep con -v 'grep'elimina el proceso grep actual.
  • Luego, use awksolo la identificación del proceso.
  • Luego mantenga este comando dentro $(...)y páselo al killcomando, para matar todo el proceso.
rashok
fuente
-1

Puede usar el siguiente comando para enumerar pid del comando. Use top o mejor use htop para ver todos los procesos en linux. Aquí quiero matar un proceso llamado

ps -ef | grep '/usr/lib/something somelocation/some_process.js'  | grep -v grep | awk '{print $2}'

Y verificar el pid. Debe ser apropiado. Para matarlos, use el comando kill.

sudo kill -9 `ps -ef | grep '/usr/lib/something somelocation/some_process.js'  | grep -v grep | awk '{print $2}'`

Por ejemplo: - es de la lista de procesos htop.

sudo kill -9 `ps -ef | grep '<process>'  | grep -v grep | awk '{print $2}'`

Esto resuelve mis problemas. Siempre esté preparado para reiniciar el proceso si accidentalmente termina un proceso.

shijin
fuente