Tuer de nombreuses instances d'un processus en cours avec une seule commande

75

Supposons que j'ai un millier d'instances ou plus d'un processus (par exemple vi) en cours d'exécution. Comment puis-je tous les tuer en un seul coup / une seule ligne / une seule commande?

Le Chevalier Noir
la source
3
Il est difficile de savoir pour quels systèmes vous souhaitez que cela fonctionne. Par exemple, sur Linux , j'utilise pkilldu procpspackage.
Deer Hunter
La question a été posée d'un point de vue général. Je ne connaissais que deux processus, comme killall et via awk / sed. Mais je voulais savoir s'il y avait d'autres moyens d'y parvenir. Si cela se fait différemment dans différents systèmes, alors je veux savoir quoi en quoi. C'est très encombrant de google, au lieu de cela, j'ai pensé à discuter avec vous tous, des gars expérimentés.
Le chevalier noir

Réponses:

97

Quel est le problème avec le bon vieux,

for pid in $(ps -ef | grep "some search" | awk '{print $2}'); do kill -9 $pid; done

Il y a moyen de rendre cela plus efficace,

for pid in $(ps -ef | awk '/some search/ {print $2}'); do kill -9 $pid; done

et d'autres variations, mais au niveau de base, cela a toujours fonctionné pour moi.

EightBitTony
la source
1
Up a voté, ne connaissait que la première variante. La seconde semble plus efficace, merci.
Le chevalier noir
5
@TheDarkKnight Le problème avec cette méthode est que vous finissez souvent par tuer plus que prévu. Écrire une "recherche" fiable est délicat. Sous Linux, utilisez pkill , qui gère la plupart des subtilités.
Gilles 'SO- arrête d'être méchant'
Je ne suis pas sûr que ce soit difficile, si vous recherchez un binaire spécifique, cela peut être assez fiable. De echo kill -9 $pidtoute façon, je le lance toujours comme une première pour que je sache ce que je reçois. Je ne suis pas sûr qu'AIX en ait pkill, qui est mon pain et beurre UNIX. Et est-ce vraiment assez grave d'être voté à la baisse - étrange.
EightBitTony
1
À moins que cela ne soit absolument nécessaire, vous devez envoyer le processus SIGTERM au lieu de SIGKILL.
Je devrais ajouter que ces 2 méthodes ne fonctionneront pas dans tous les shells, par exemple, cela ne marchera pascsh
non sequitor
38

Utilisez killall,

killall vi

Cela va tuer toutes les commandes nommées 'vi'

Vous pouvez également ajouter un signal, par exemple SIGKILL

killall -9 vi

Marguerite
la source
C'est vrai, vous pouvez aussi ajouter le signal que vous voulez, commekillall -9 vi
Hola Soy Edu Feliz Navidad
1
Je ne pense pas que killall en est la solution: tuer par fichier ne fonctionne que pour les exécutables maintenus ouverts pendant l'exécution, c'est-à-dire que les exécutables impurs ne peuvent pas être tués de cette façon. Taper le nom de killall peut ne pas avoir l'effet souhaité sur les systèmes non-Linux, en particulier lorsque cela est fait par un utilisateur privilégié. Que se passe-t-il si j'essaie de supprimer un grand nombre d'instances d'un processus non-Linux? killall -w ne détecte pas si un processus a disparu et est remplacé par un nouveau processus avec le même PID entre les analyses. Si les processus changent de nom, killall risque de ne pas pouvoir leur correspondre correctement.
Le chevalier noir
13
Veuillez noter que cela ne fonctionne que sous Linux et BSD. Sur Solaris et certains autres systèmes, killallfait exactement ce que son nom l'indique ... tue le processus init.
Bobby
2
Sous AIX, "annule tous les processus que vous avez démarrés, à l'exception de ceux produisant le processus killall".
EightBitTony
31

pkillC’est ce que je recommande, s’il est disponible ( Linux , FreeBSD , NetBSD , OpenBSD , Solaris ). Vous pouvez spécifier des processus à l'aide du nom de la commande, de la ligne de commande complète ou d'autres critères. Par exemple, pkill visupprime tous les programmes dont le nom de commande contient la sous-chaîne vi. Pour ne tuer que les processus appelés vi, utilisez pkill -x vi. Pour ne tuer que les processus appelés viavec un dernier argument se terminant par .conf, utilisez pkill -fx 'vi.*\.conf'.

Pour voir la liste des PID auxquels pkillenvoyer un signal, utilisez pgrep, qui a exactement la même syntaxe, à la différence près qu'il n'accepte pas le nom ou le numéro du signal. Pour plus d'informations sur ces processus, exécutez

ps -p "$(pgrep …)"

Sous Linux, vous avez ps -p $(pgrep -d, …)plutôt besoin (c'est un bogue: celui de Linux psn'est pas compatible POSIX).

Un autre moyen courant d'identifier les processus à éliminer est les processus qui ont un fichier ouvert (qui peut être l'exécutable du processus). Vous pouvez les lister avec fuser; utiliser fuser -kpour leur envoyer un signal. Par exemple, fuser -k /usr/bin/findtue tous les éléments en cours d'exécution de find.

Si un processus incontrôlé continue à falsifier, vous devrez peut-être supprimer tout le groupe de processus en même temps. Un groupe de processus est identifié par le négatif de son chef, qui est le processus ancêtre de tous les processus du groupe. Pour voir le groupe de processus auquel appartient un processus, exécutez-le ps -o pgid(plus toute option permettant de sélectionner le ou les processus à afficher). Si vous déterminez que vous voulez tuer le chef de groupe de processus 1234 et tous ses enfants, courir kill -1234ou kill -HUP -1234ou tout autre signal.

Si vous ne trouvez pas de meilleur moyen, utilisez la commande psavec les options appropriées pour répertorier tous les processus et les filtrer avec grepou une autre commande de filtrage de texte. Veillez à ne pas faire correspondre accidentellement d'autres processus exécutant une commande portant un nom similaire ou avec un argument contenant ce nom. Par exemple:

kill $(ps -o pid -o comm | awk '$2 == "vi" {print $1}')

N'oubliez pas que votre commande grepou awkelle-même peut être répertoriée dans la pssortie ( pset que la commande de filtrage est démarrée en parallèle, son affichage dépend du moment choisi). Ceci est particulièrement important si les arguments de commande sont inclus dans la pssortie.

Gilles, arrête de faire le mal
la source
Merci beaucoup, c'est vraiment génial. Ce que vous avez donné est une sorte de tutoriel. Merci encore . Up a voté
The Dark Knight
6

pkillc'est très bien ici. Vous pouvez lui donner beaucoup de paramètres pour affiner le motif.

Nils
la source
Non disponible sur toutes les unités UNIX et aucune mention d'un système d'exploitation UNIX ou de type UNIX spécifique dans la question.
EightBitTony
@EightBitTony pkillest disponible sous Linux, BSD et Solaris. Donc, il a une plus grande propagation que killall.
Nils
Je suis d'accord, mais killall est encore plus problématique car il y a plusieurs outils du même nom, qui semblent avoir un comportement radicalement différent. Je n'aime pas les réponses killall non plus. pkill n'existe pas sous AIX ou HP-UX et malgré ce que certaines personnes aiment croire, il existe toujours une importante base d'UNIX non Linux dans le monde.
EightBitTony
1
@EightBitTony c'est pourquoi votre réponse est acceptée. Mais je ne l’utiliserais pas sous Solaris (qui est aussi sous Unix).
Nils
6

La meilleure façon de le faire est d’abord de vérifier que vous obtenez les bons ID de processus avec:

pgrep -f [part_of_a_command]

Si le résultat est comme prévu. Aller avec:

pkill -f [part_of_a_command]
Tahsin Turkoz
la source
ou utiliser:pgrep -f "command name"
Magne
3

Intéressant personne n'a mentionné celui-ci. pidof génère des pids de processus séparés par des espaces correspondant au nom de processus transmis. En tant que tel, vous pouvez directement utiliser sa sortie avec killsans tuyauterie. Sur Arch Linux, j'utilise

kill -9 $(pidof <proc name>)

L'inconvénient de cette solution est qu'elle ne permet pas l'utilisation d'expressions régulières.

sherrellbc
la source
0

Je vous suggère d'essayer pkill.

Ex: ps -ef | pkill -f command

Pour afficher la liste de tous les processus à tuer en premier, essayez de pgrep:

Ex: ps -ef | pgrep -f command

Ankit Vashistha
la source
1
Quel est le but de la canalisation de la sortie de ps -efdans pkillou pgrep? Ces commandes ne lisent pas depuis l'entrée standard.
Kusalananda
0

Vous pouvez tuer plusieurs processus différents en utilisant la commande ci-dessous

pkill -9 -f "\.\/.+\s\.|process1|process2|process3\[^"

Notez que cela va tuer le processus qui correspond au modèle ci-dessus, signifie process1abc process2def process3ghiaussi être tué.

SandPox
la source
-1

pgrep "name-of-application" | xargs kill -9

Était assez simple à retenir et a bien fonctionné pour moi.

Horv
la source
-2
$ ps -eaf  | grep "xyz" | grep -v grep | awk 'print $2' | xargs kill
utilisateur110509
la source
-2
ps -ef | pgrep -f "search" | xargs kill -9  
Avijit Dhar
la source