Quelle est la bonne façon de vérifier si un PID est en cours d'exécution?

12

J'ai un .pidfichier et je dois vérifier si le processus est en cours d'exécution. Jusqu'à présent, j'ai trouvé deux options

kill -0 `cat something.pid`

qui affiche une erreur si le pid ne fonctionne pas. Je sais que cela peut être redirigé vers /dev/null, mais cela me fait penser que ce n'est pas la meilleure solution.

La seconde solution serait d’utiliser ps, qui imprime cependant aussi sur le STDOUT

ps -ef `cat something.pid`

Est-il normal de rediriger la sortie vers /dev/nullet d'utiliser simplement le code d'état renvoyé, ou est-ce un signe que je fais quelque chose de mal et j'ai besoin d'une commande différente?

Jakub Arnold
la source
5
À utiliser kill -0car il est conforme à la norme (POSIX).
Anders

Réponses:

9

pour la plupart des distributions Linux, l'énumération de / proc / {pid} est un bon moyen d'obtenir des informations sur les processus en cours d'exécution, et généralement sur la façon dont les commandes de l'espace utilisateur comme "ps" communiquent avec le noyau. Ainsi, par exemple, vous pouvez le faire;

[ -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"

Edit: vous devez vérifier que kpid est défini, mais cela est plus utile car il retournera "n'existe pas" pour unset $ {kpid}

[ -n "${kpid}" -a -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"
Tom H
la source
@SteveMuster Cela rendrait la réponse spécifique à Linux. Il n'y a pas de / proc sur OSX. Et je pense qu'il n'y a pas de / proc sur BSD.
ash
Notez que vous devez vous assurer qu'il ${kpid}existe
Wilf
@Wilf Je l'ai édité, donc il retourne "le processus n'existe pas" pour unset $ {kpid}
Tom H
Merci - Je faisais un script qui vérifie un PID en utilisant une méthode similaire et cela n'a pas fonctionné jusqu'à ce que je trouve que c'était le problème :)
Wilf
6

Comme l'a noté Anders, vous devez utiliser kill -0pour la conformité POSIX.

Sur les systèmes Linux, vous pouvez également vérifier l'existence d'un fichier dans le système de fichiers / proc, par exemple,

-f /proc/$(cat something.pid)/status
cjc
la source
1

Si cela se trouve dans un script (ce qui, je suppose, est le cas, car vous avez peur d'imprimer sur stdout), voici comment vous pouvez le faire:

if ps -p $(cat something.pid) > /dev/null 2>&1
then
    kill $(cat something.pid)
else
    # Deal with the fact that the process isn't running
    # i.e. clear up the pid file
fi

Le ps -precherche un processus avec le pid spécifié dans quelque $()chose.pid (la syntaxe est une version légèrement plus récente du backtick. Backtick a besoin de s'échapper dans certaines circonstances que le nouveau formulaire ne fait pas). Les 2>&1redirections stderr pour cette commande également.

Si la ps -pcommande ne trouve pas le processus avec ce PID, elle se termine avec une erreur> 0 et ainsi elses'exécute. Sinon, la killdéclaration. Vous pouvez annuler ce qui précède si vous le souhaitez en faisant:

if ! ps -p ...

J'espère que cela répond à votre question. Évidemment, soyez prudent et testez beaucoup lorsque vous utilisez des commandes dangereuses telles que kill.

webtoe
la source
1

Voici quelques options:

  • Si vous écrivez un script init (par exemple celui à placer /etc/init.d/) et si vous utilisez une distribution basée sur Debian, vous feriez mieux d'utiliser start-stop-daemon:
    # start-stop-daemon -T -p $PIDFILE -u $USER_NAME -n $NAME
    Vous devriez obtenir le code de sortie 0 s'il est en cours d'exécution.
  • Vous pouvez utiliser pgrep et pkill du procpspackage:
    pgrep --pidfile $PIDFILE
jollyroger
la source
0

Si vous avez un fichier pid, vous pouvez utiliser pgrep pour vérifier si le processus est en cours d'exécution:

    if pgrep -F something.pid; then
        echo "Running"
    else
        echo "Not running"
    fi
Dima L.
la source