216 votes

Bash : comment vérifier l'existence d'un identifiant de processus (PID)

Dans un script bash, je veux faire ce qui suit (en pseudo-code) :

if [ a process exists with $PID ]; then

    kill $PID 

fi

Quel est le bash approprié pour l'instruction conditionnelle ?

Merci

303voto

FDS Points 583

Le meilleur moyen est :

if ps -p $PID > /dev/null
then
   echo "$PID is running"
   # Do something knowing the pid exists, i.e. the process with $PID is running
fi

Le problème avec :

kill -0 $PID

est que le code de sortie sera différent de zéro même si le pid est en cours d'exécution et que vous n'avez pas la permission de le tuer. Par exemple :

kill -0 1

et

kill -0 $non-running-pid

ont un code de sortie indiscernable (non nul) pour un utilisateur normal, mais le processus init (PID 1) est certainement en cours d'exécution.

DISCUSSION

Les réponses concernant les conditions kill et race sont tout à fait correctes si le corps du test est un "kill". Je suis venu chercher la réponse générale " Comment tester l'existence d'un PID en bash ? ".

La méthode /proc est intéressante, mais dans un certain sens, elle brise l'esprit de l'abstraction de la commande "ps", c'est-à-dire que vous n'avez pas besoin d'aller chercher dans /proc car que se passe-t-il si Linus décide d'appeler le fichier "exe" autrement ?

204voto

Pour vérifier l'existence d'un processus, utilisez

kill -0 $PID

Mais comme @unwind l'a dit, si vous allez le tuer de toute façon, il suffit de

kill $PID

ou vous aurez une condition de course.

Si vous voulez ignorer la sortie texte de kill et faire quelque chose en fonction du code de sortie, vous pouvez

if ! kill $PID > /dev/null 2>&1; then
    echo "Could not send SIGTERM to process $PID" >&2
fi

77voto

user2683246 Points 101
if [ -e /proc/$PID ]

ou

if [ -n $(ps -p$PID -o pid=) ]

Dans cette dernière forme, -o pid= est un format de sortie permettant d'afficher uniquement la colonne d'identification du processus, sans en-tête.

40voto

oherrala Points 390

ps avec -p $PID peut le faire :

$ ps -p 3531
  PID TTY          TIME CMD
 3531 ?        00:03:07 emacs

12voto

elcuco Points 3953

Vous avez deux possibilités :

Commençons par rechercher une application spécifique dans mon ordinateur portable :

[root@pinky:~]# ps fax | grep mozilla
 3358 ?        S      0:00  \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2    S+     0:00              \_ grep mozilla

Tous les exemples rechercheront désormais le PID 3358.

Premier moyen : Exécutez "ps aux" et recherchez le PID dans la deuxième colonne. Dans cet exemple, je cherche firefox, puis son PID :

[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358

Donc votre code sera :

if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
    kill $PID 
fi

Deuxième voie : Cherche juste quelque chose dans le /proc/$PID répertoire. J'utilise "exe" dans cet exemple, mais vous pouvez utiliser n'importe quoi d'autre.

[root@pinky:~]# ls -l /proc/3358/exe 
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash

Donc votre code sera :

if [ -f /proc/$PID/exe ]; then
    kill $PID 
fi

BTW : quel est le problème avec kill -9 $PID || true ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X