Rechercher et tuer un processus sur une seule ligne en utilisant bash et regex


650

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

La façon dont je le fais maintenant est la suivante:

[~]$ 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 l'ID de processus automatiquement et le tuer sur la même ligne?

Comme ça:

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

3
Crois moi! : 'D La première réponse que vous avez choisie est beaucoup plus complexe que la solution que vous avez indiquée dans votre réponse. Je préfère choisir ta voie.
Santosh Kumar

meilleure façon de vérifier si le processus existe: stackoverflow.com/questions/3043978/…
Trevor Boyd Smith

Réponses:


1400

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:

  • Le psvous donne la liste de tous les processus.
  • Les grepfiltres basés sur votre chaîne de recherche [p]sont une astuce pour vous empêcher de récupérer le grepprocessus lui-même.
  • Le awkjuste vous donne le deuxième champ de chaque ligne, qui est le PID.
  • La $(x)construction signifie exécuter xpuis prendre sa sortie et la mettre sur la ligne de commande. La sortie de ce pspipeline à l'intérieur de cette construction ci-dessus est la liste des ID de processus, vous vous retrouvez donc avec une commande comme 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 terminer tous les dormeurs.


Expliquant le grep '[p]ython csp_build.py'bit un peu plus en détail:

Lorsque vous ne sleep 3600 &suiviez par ps -ef | grep sleep, vous avez tendance à deux processus avec sleepen elle, la sleep 3600et grep sleep(parce qu'ils ont tous les deux sleepen eux, ce n'est pas sorcier).

Cependant, ps -ef | grep '[s]leep'ne créera pas de processus avec sleep, il crée à la place grep '[s]leep'et voici le bit délicat: le grepne le trouve pas car il recherche l'expression régulière "n'importe quel caractère de la classe de caractères [s](qui est s) suivi par leep.

En d'autres termes, il est à la recherche, sleepmais le processus grep est celui grep '[s]leep'qui ne s'y trouve pas sleep.

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

  • c'est un processus de moins que l'ajout | grep -v grep; et
  • c'est élégant et sournois, une combinaison rare :-)

2
@paxdiablo, pouvez-vous fournir un lien pour cela? Je suis déconcerté pourquoi cela fonctionne.
glenn jackman

58
Vous ne pouvez utiliser que awk - ps aux | awk '/ [b] eam / {print $ 2}' , aucun grep nécessaire
Yola

20
Mieux vaut utiliser uniquement pgrep ou pkill
NGix

2
Il y a un petit problème - si le processus a déjà été interrompu, cette ligne de killsera produite avec la sortie standardkill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Lionel Chan

5
Au lieu de grep '[p]ython csp_build.py'vous pouvez également utiliser: kill $(ps aux | grep 'python csp_build.py' | grep -v grep | awk '{print $2}'). grep -vrenvoie des lignes non appariées.
usandfriends

138

si vous avez pkill,

pkill -f csp_build.py

Si vous souhaitez uniquement effectuer une grep contre le nom du processus (au lieu de la liste complète des arguments), laissez-la désactivée -f.


1
Rien ne s'est produit lorsque j'ai testé cela.
Orjanp

8
utilisez d'abord pgrep pour vérifier que vous avez bien accueilli le processus correct. puis utilisez à nouveau pkill sur le motif correct.
ghostdog74

18
+1. pgrepet pkilltravaillez aussi longtemps que vous prenez soin de spécifier le processus correctement. Par défaut, seul le nom du processus est mis en correspondance, ce qui est presque certainement juste "python" dans ce cas. Utilisez pgrep -f "python csp_build.py"pour faire correspondre la commande complète.
mr.spuratic

3
Vous devrez peut-être forcer la mise à mort avecpkill -9 -f csp_build.py
studgeek

1
Cela devrait vraiment être la réponse acceptée et votée; ces autres avec tous les awk'ing sont un peu inutiles. J'espère que les gens qui trouvent cette page lue au-delà de cette première réponse.
Jason C

89

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
  • Run kill -9 5124, kill -9 5373etc (kill -15 est plus gracieux mais légèrement 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. mot-clé p
    • listes sur tous les P rocessus contenant mot - clé
    • utilisation par exemple: p csp_build, p pythonetc.

code bash_profile:

# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}
  1. mot clé ka
    • K ills A ll processus qui ont ce mot-clé
    • utilisation par exemple: ka csp_build, ka pythonetc.
    • option kill niveau 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"
}

Rappel - N'oubliez pas de redémarrer le shell bash (terminal) pour charger les nouvelles fonctions. OU exécutez source ~/.bash_profiledans le shell actuel pour importer les nouvelles fonctions (c'est ce que je préfère).
a20

Comme beaucoup d'autres réponses ici, cela souffre monumentalement d' une utilisation inutile degrep . N'oubliez pas que tout ce qui ressemble grep x | awk '{ y }'est généralement meilleur et souvent plus robuste si vous le remplacez parawk '/x/ { y }'
tripleee

1
@tripleee le site Web auquel vous créez un lien vous appartient, n'est-ce pas? Je remarque que vous le liez partout dans les différentes sections de commentaires. Essayez-vous de construire le référencement?
a20

Non, je n'ai aucun intérêt pour le référencement. J'espère sensibiliser.
tripleee

1
.. en créant un lien vers votre site Web comme s'il s'agissait d'un site d'autorité établi. Agréable. De plus, grep est plus rapide .
a20

16
killall -r regexp

-r, --regexp

Interpréter le modèle de nom de processus comme une expression régulière étendue.


15

Essayez d'utiliser

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill

J'ai dû changer un peu. Cela a fonctionné. Merci. :) ps aux | grep 'python csp_build.py' | tête -1 | coupe -d "" -f 5 | xargs kill
Orjanp

3
ps aux | grep 'python csp_build.py' | awk '{print $2}' | xargs killtravaillé pour moi. Thanx
Rasika Perera

N'oubliez pas, les enfants, Awk peut tout grepfaire, et la plupart de façon simple et élégante. Le cas trivial de grep x y | awk '{ z }'est toujours mieux écrit awk '/x/ { z }' y- voir aussi utilisation inutile degrep .
tripleee

12

Vous ne pouvez utiliser que pkill '^python*' pour tuer des processus d'expression régulière.

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


8

Utilisez pgrep - disponible sur de nombreuses plateformes:

kill -9 `pgrep -f cps_build`

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


2
Si vous en avez pgrep, vous en aurez également pkill. Comme toujours, n'utilisez paskill -9 sauf si vous savez pourquoi kill -15(par défaut) ou kill -2ne fonctionnera pas.
tripleee

Cela ressemble à une pire paraphrase de la réponse de @ nathanael qui omet la mauvaise direction -9et utilise la syntaxe de substitution de commande moderne appropriée. Votez plutôt pour cela; bien sûr, la pkillréponse est encore meilleure.
tripleee

@tripleee Dans ce cas, tuer -9 est exactement ce que je veux - mettre fin à tous les délinquants avec un préjudice extrême. De plus, j'utilise kill -9 depuis de nombreuses années sans aucun problème. À mon avis, il y aura toujours un camp de puristes contre un camp de réalistes, et j'appartiens à ce dernier (dans ce domaine).
a20

Vous avez manqué la partie "à moins que vous ne sachiez pourquoi"? Je suis tout pour faire avancer les choses, mais c'est l'une des façons courantes de se tirer une balle dans le pied jusqu'à ce que vous compreniez ce que cela -9signifie réellement.
tripleee

@tripleee hey tripleee, j'ai récemment trouvé que vous aviez raison, kill -15 est un meilleur choix car il donne à l'application une chance de se tuer gracieusement. J'ai changé mon code en conséquence: stackoverflow.com/a/30486159/163382
20

7

Cela renverra le pid uniquement

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, ce pgrepserait mieux.

S'il y a plusieurs processus en cours d'exécution 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 vous inquiétez de 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 signalou man signaletman pgrep


5

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 les backtics exécutent l'instruction qui est imprimée.

Mais une solution beaucoup plus propre serait que le processus python stocke son identifiant de processus dans / var / run et alors vous pouvez simplement lire ce fichier et le tuer.


Ne tuerez-vous pas alors les processus 5124 et 5373? Je suppose que ce n'est pas un problème.
Orjanp

cela ne devrait pas être un problème, mais vous pouvez toujours ajouter un autre grep pour exclure le processus grep: "grep -v grep" entre grep et awk
Alexander Kjäll

Testé avec une commande légèrement modifiée. Mais cela n'a pas tué le processus, seulement imprimé kill <pid>. ps auxf | grep '[p] ython csp_build.py' | awk '{print "kill" $ 2}'
Orjanp

Il suffit d'échanger l'instruction d'impression "kill" $ 2 avec un système ("kill" $ 2). Alors ça marche. :)
Orjanp

5

Ma tâche était de tuer tout ce qui correspond à l'expression rationnelle qui est placé dans un répertoire spécifique (après les tests au sélénium, 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

L' -9option de killest peut-être trop agressive. Cela ne leur permet pas de libérer leurs ressources.
Birei

Agréable! Le seul à considérer le fait qu'il pourrait y avoir plus d'un processus de correspondance! Une petite remarque: vous voudrez peut-être ajouter un "grep -v grep" ou quelque chose comme ça aux tuyaux, pour vous assurer que le processus grep lui-même n'apparaît pas dans votre liste de processus.
Brad Parks

killaccepte plusieurs processus, donc la boucle est fondamentalement inutile; et comme indiqué ailleurs sur cette page, vous ne devriez pas utiliser à kill -9moins que vous sachiez que le processus ne répondra pas seulement kill.
tripleee

supprimer -9 n'est pas un gros problème, pourquoi downvote. Vous feriez mieux de modifier la réponse.
Serge

5

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

kill -SIGTERM $(pgrep -i midori)


3

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é de chaîne, j'empêche de faire correspondre ce processus lui-même.


Pour une raison quelconque, je ne reçois pas un hit sur "python csp_build.py". Mais "python" seul frappe.
Orjanp

3
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15

Impossible de +1 en raison de la limite quotidienne, mais l'utilisation psde l' -ooption en vaut la peine.
P Shved

ps ne me donne pas grand chose. [~] $ ps PID TTY TIME CMD 6365 pts / 6 00:00:00 ps 29112 pts / 6 00:00:00 bash
Orjanp

3

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

2

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

kill $(pgrep 'python csp_build.py')

1

Tuer nos propres processus démarrés à partir d'un PPID commun est assez fréquent, pkill associé au –Pdrapeau est un gagnant pour moi. En utilisant l'exemple de @ 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

Vous n'avez pas besoin du commutateur utilisateur pour ps.

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

1

Dans certains cas, j'aimerais tuer des processus simultanément comme ceci:

➜ ~ dormir 1000 &
[1] 25410
➜ ~ dormir 1000 &
[2] 25415
➜ ~ dormir 1000 &
[3] 25421
➜ ~ pidof sommeil
25421 25415 25410
➜ ~ tuer `pidof sleep`
[2] - 25415 a mis fin au sommeil 1000                                                             
[1] - 25410 a mis fin au sommeil 1000
[3] + 25421 a mis fin au sommeil 1000

Mais je pense que c'est un peu inapproprié dans votre cas (il se peut qu'il y ait python a, python b, python x ... en arrière-plan).


1

Si pkill -f csp_build.pyne tue pas le processus, vous pouvez ajouter -9pour envoyer un signal de mise à mort qui ne sera pas ignoré. c'est à direpkill -9 -f csp_build.py


1

La solution serait de filtrer les processus avec le modèle exact, d'analyser le pid et de construire une liste d'arguments pour exécuter les processus de suppression:

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

Explication de la documentation:

L' utilitaire ps affiche une ligne d'en-tête, suivie de lignes contenant des informations sur tous vos processus qui ont des terminaux de contrôle.

-e Afficher des informations sur les processus des autres utilisateurs, y compris ceux

-f Affiche l'uid, le pid, le pid parent, l'utilisation récente du processeur, le démarrage du processus

L' utilitaire grep recherche les fichiers d'entrée donnés, en sélectionnant les lignes

-e motif, --regexp = motif Spécifiez un motif utilisé lors de la recherche de l'entrée: une ligne d'entrée est sélectionnée si elle correspond à l'un des motifs spécifiés. Cette option est particulièrement utile lorsque plusieurs options -e sont utilisées pour spécifier plusieurs modèles, ou lorsqu'un modèle commence par un tiret (`- ').

xargs - construire des listes d'arguments et exécuter l'utilitaire

kill - terminer ou signaler un processus

signal numéro 9 - KILL (kill non capturable, non ignorable)

Exemple :

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

0

J'utilise cela pour tuer Firefox quand il est critiqué et basé sur le processeur :) 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)


Le remplacement grep Firefox | awk 'NR == 1 { next } ...'par awk 'NR == 1 || $11 !~ /Firefox/ { next } ...'non seulement enregistre un processus, mais améliore également la précision. Il n'est pas difficile non plus de se débarrasser d' sort | uniqAwk pur (alors que bien sûr uniq | sortc'est juste faux - il manquera tous les doublons qui ne sont pas adjacents, et masquera l'erreur en triant inutilement la sortie de uniq).
tripleee

0

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: cela ne tuera PAS les processus qui ont "grep" dans leurs lignes de commande.


1
Comme les nombreuses, nombreuses autres réinventions du hangar à yacks, cela est criblé d' utilisation inutilegrep et d'autres antipatterns de script shell courants.
tripleee

-1

La commande suivante sera utile:

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

par exemple., 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 le processus est toujours bloqué, utilisez l'extension "-9" pour hardkill, comme suit:

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

J'espère que cela pourra aider...!


-1

Trouvez et tuez tous les processus en une seule ligne dans bash.

kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})
  • ps -ef | grep '<exe_name>'- Donne la liste des détails du processus en cours (uname, pid, etc.) qui correspondent au modèle. La liste de sortie inclut grepégalement cette commande qui la recherche. Maintenant, pour tuer, nous devons ignorer celagrep processus de commande.
  • ps -ef | grep '<exec_name>' | grep -v 'grep'- L'ajout d'un autre grep avec -v 'grep'supprime le processus grep actuel.
  • Ensuite, utilisez awkuniquement l'ID de processus.
  • Ensuite, gardez cette commande à l'intérieur $(...)et passez-la à la killcommande, pour tuer tous les processus.

-1

Vous pouvez utiliser la commande ci-dessous pour répertorier le pid de la commande. Utilisez top ou mieux utilisez htop pour afficher tous les processus sous Linux. Ici, je veux tuer un processus nommé

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

Et vérifiez le pid. Il doit être approprié. Pour les tuer, utilisez la commande kill.

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

Par exemple: - provient de la liste des processus htop.

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

Cela résout mes problèmes. Soyez toujours prêt à redémarrer le processus si vous tuez accidentellement un processus.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.