web-dev-qa-db-fra.com

Trouvez et tuez un processus sur une ligne en utilisant bash et regex

J'ai souvent besoin de tuer un processus pendant la programmation.

Voici comment je le fais:

[~]$ 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

Comment puis-je extraire automatiquement l'identifiant du processus et le tuer dans la même ligne?

Comme ça:

[~]$ ps aux | grep 'python csp_build.py' | kill <regex that returns the pid>
571
Orjanp

Dans bash, vous devriez pouvoir faire:

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

Les détails de son fonctionnement sont les suivants:

  • La ps vous donne la liste de tous les processus.
  • Les filtres grep basés sur votre chaîne de recherche, _[p]_ sont une astuce pour vous empêcher de prendre le processus grep lui-même.
  • Le awk vous donne simplement le deuxième champ de chaque ligne, qui est le PID.
  • La construction $(x) signifie exécuter x puis prendre sa sortie et la placer sur la ligne de commande. La sortie de ce pipeline ps à l'intérieur de la construction ci-dessus est la liste des ID de processus. Vous obtenez donc une commande telle que _kill 1234 1122 7654_.

Voici une transcription le montrant en action:

_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
_

et vous pouvez le voir mettre fin à tous les dormeurs.


Expliquer le bit _grep '[p]ython csp_build.py'_ de manière un peu plus détaillée:

Lorsque vous faites _sleep 3600 &_ suivi de _ps -ef | grep sleep_, vous avez tendance à obtenir deux processus avec sleep, _sleep 3600_ et _grep sleep_ (parce qu'ils ont tous les deux sleep en eux, ce n'est pas sorcier).

Cependant, _ps -ef | grep '[s]leep'_ ne créera pas de processus contenant sleep, il créera plutôt _grep '[s]leep'_ et voici le problème le plus difficile: le grep ne le trouve pas car il est à la recherche pour l'expression régulière "tout caractère de la classe de caractères _[s]_ (qui est s) suivi de leep.

En d'autres termes, il recherche sleep mais le processus grep est _grep '[s]leep'_ qui n'a pas sleep.

Quand on m'a montré ceci (par quelqu'un ici sur SO), j'ai immédiatement commencé à l'utiliser parce que

  • c'est un processus de moins que d'ajouter _| grep -v grep_; et
  • c'est élégant et sournois, une combinaison rare :-)
1270
paxdiablo

si vous avez pkill,

pkill -f csp_build.py

Si vous ne voulez que grep par rapport au nom du processus (au lieu de la liste d'arguments complète), alors laissez -f.

122
ghostdog74

Bon mot:

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

  • Imprimez la colonne 2: _awk '{print $2}'_
  • Sudo est facultatif
  • Exécuter _kill -9 5124_, _kill -9 5373_ etc (kill -15 est plus gracieux mais un peu plus lent)

Prime:

J'ai également 2 fonctions de raccourci définies dans mon .bash_profile (~/.bash_profile est pour osx, vous devez voir ce qui fonctionne pour votre machine * nix).

  1. p mot-clé
    • liste tous les P processus contenant le mot clé
    • utilisation, par exemple: _p csp_build_, _p python_ etc

code bash_profile:

_# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}
_
  1. ka mot-clé
    • K maux A Tous les processus contenant ce mot-clé
    • utilisation, par exemple: _ka csp_build_, _ka python_ etc
    • niveau de suppression facultatif, par exemple: _ka csp_build 15_, _ka python 9_

code 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"
}
_
79
a20

Essayez d'utiliser

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill
14
Rahul
killall -r regexp

-r, --regexp

Interpréter le modèle de nom de processus en tant qu'expression régulière étendue.

13
Miron Yanovskiy

Vous ne pouvez utiliser que pkill '^python*' pour la suppression du processus regex.

Si vous voulez voir ce que vous allez tuer ou trouver avant de tuer, utilisez simplement pgrep -l '^python*' où -l affiche également le nom du processus. Si vous ne voulez pas utiliser pkill, utilisez simplement:

pgrep '^python*' | xargs kill

9
NGix

Utilisez pgrep - disponible sur de nombreuses plateformes:

kill -9 `pgrep -f cps_build`

pgrep -f retournera tous les PID avec une coïncidence "cps_build"

6
vr286

Pour tuer le processus par le mot clé midori, par exemple:

kill -SIGTERM $(pgrep -i midori)

5
l3v1ath4n

vous pouvez le faire avec awk et backtics

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

$ 2 dans awk imprime la colonne 2 et le backtics exécute la déclaration imprimée.

Mais une solution beaucoup plus propre consisterait pour le processus python à stocker son identificateur de processus dans/var/run. Vous pourrez alors simplement lire ce fichier et le tuer.

5
Alexander Kjäll

Ma tâche consistait à supprimer tout ce qui correspond à l'expression rationnelle placée dans un répertoire spécifique (après les tests de Selenium, tout ne s'est pas arrêté). Cela a fonctionné pour moi:

for i in `ps aux | egrep "firefox|chrome|Selenium|opera"|grep "/home/dir1/dir2"|awk '{print $2}'|uniq`; do kill $i; done
5
Serge

Cela retournera le pid seulement

pgrep -f 'process_name'

Donc, pour tuer n'importe quel processus en une seule ligne:

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

ou, si vous connaissez le nom exact du processus, vous pouvez également essayer pidof:

kill -9 $(pidof 'process_name')

Mais, si vous ne connaissez pas le nom exact du processus, pgrep serait préférable.

Si plusieurs processus s'exécutent avec le même nom et que vous voulez tuer le premier, alors:

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

Notez également que si vous êtes préoccupé par la sensibilité à la casse, vous pouvez ajouter l'option -i comme dans grep. Par exemple:

kill -9 $(pgrep -fi chrome)

Plus d'informations sur les signaux et pgrep sur man 7 signal ou man signal et man pgrep

4
Rakib Fiha

Une méthode utilisant uniquement awk (et ps):

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

En utilisant le test d'égalité des chaînes, j'empêche de faire correspondre ce processus lui-même.

3
schot

Donner -f à pkill

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

le chemin exact du fichier .py est

# ps ax | grep fritzcap.py
 3076 pts/1    Sl     0:00 python -u /usr/local/bin/fritzcap.py -c -d -m
3
Robert1968
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15
3
Vijay

J'ai commencé à utiliser quelque chose comme ça:

kill $(pgrep 'python csp_build.py')
2
Nathanael

Dans certains cas, j'aimerais tuer simultanément les processus de cette façon:

Sleep ~ sommeil 1000 & 
 [1] 25410 
 ➜ ~ sommeil 1000 & 
 [2] 25415 
 ~ Sommeil 1000 & 
 [3 ] 25421 
 ➜ ~ pidof de sommeil 
 25421 25415 25410 
 ~ Kill `pidof sleep` 
 [2] - 25415 sommeil terminé 1000 
 [ 1] - 25410 sommeil terminé 1000 
 [3] + 25421 sommeil terminé 1000

Mais, je pense que c'est un peu inapproprié dans votre cas. (Peut-être qu'il y a-t-il en cours d'exécution python a, python b, python x ... dans l'arrière-plan.)

1
kashu.org

Tuer nos propres processus à partir d'un commun PPID est assez fréquent, pkill associé au drapeau –P est un gagnant pour moi. En utilisant l'exemple @ 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
1
Juan Diego Godoy

Vous n'avez pas besoin du changement d'utilisateur pour ps.

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

J'utilise gkill processname, où gkill est le script suivant:

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

Remarque: il ne sera pas tuer les processus qui ont "grep" dans leurs lignes de commande.

0
Kostyantyn

J'utilise ceci pour tuer Firefox quand il s'agit d'un script critiqué et d'un cpu bashing :) Remplacez 'Firefox' par l'application que vous voulez mourir. Je suis sur le shell Bash - OS X 10.9.3 Darwin.

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

0
mrhassell