J'écris un script Perl qui analyse les fichiers journaux pour collecter les PID, puis vérifie si ce PID est en cours d'exécution. J'essaie de penser à la meilleure façon de faire ce chèque. Évidemment, je pourrais faire quelque chose comme:
system("ps $pid > /dev/null") && print "Not running\n";
Cependant, je préfère éviter l'appel système si possible. J'ai donc pensé pouvoir utiliser le /proc
système de fichiers (la portabilité n'est pas un problème, cela fonctionnera toujours sur un système Linux). Par exemple:
if(! -d "/proc/$pid"){
print "Not running\n";
}
Est-ce sûr? Puis-je toujours supposer que s'il n'y a pas de /proc/$pid/
répertoire, le PID associé ne fonctionne pas? Je m'attends à ce que puisque l'AFAIK ps
lui-même obtient ses informations de /proc
toute façon, mais comme il s'agit du code de production, je veux en être sûr.
Ainsi, peut-il y avoir des cas où un processus en cours d'exécution n'a pas de /proc/PID
répertoire ou où un /proc/PID
répertoire existe et le processus n'est pas en cours d'exécution? Y a-t-il une raison de préférer l'analyse ps
au lieu de vérifier l'existence du répertoire?
la source
kill
fonction perl utilisant le signal 0 qui ne tue pas mais dit si vous pouvez le faire (c'est-à-dire que vous avez besoin d'une autorisation pour signaler ce processus).kill -0
c'est la meilleure), cela vous indique uniquement s'il existe un processus en cours avec le PID donné . Il ne vous dit pas si le processus sera toujours en cours d'exécution une milliseconde plus tard, et il ne vous indique pas si le processus est celui qui vous intéresse ou un processus indépendant qui a reçu le même PID après la mort du processus intéressant . C'est presque toujours une erreur de tester si un PID donné fonctionne : il y a très peu de circonstances où cela n'est pas sujet aux conditions de course.Réponses:
La fonction perl
kill(0,$pid)
peut être utilisée.Si le code retour est 1, le PID existe et vous êtes autorisé à lui envoyer un signal.
Si le code retour est 0, vous devez vérifier $ !. Il peut s'agir d'EPERM (autorisation refusée), ce qui signifie que le processus existe ou ESRCH, auquel cas le processus n'existe pas.
Si votre code de vérification est en cours d'exécution,
root
vous pouvez simplifier cela en vérifiant simplement le code retour de kill; 0 => erreur, 1 => okPar exemple:
Cela peut être transformé en une fonction simple
la source
if (!kill(0,$pid) && $! =~ /No such process/){ exit; }
ou similaire. J'aimeErrno
mieux votre solution, merci. Bien que j'y vais probablement, j'attendrai un moment au cas où quelqu'un pourrait répondre à la question Linux sous-jacente./proc
est alors monté chaque PID visible dans l'espace de noms sera présent, de sorte que votre-d /proc/$pid
essai ne fonctionne ... mais il implique de sortir du système de fichiers plutôt que d' utiliser des appels système natif.system
appel" - c'est-à-dire un appel à lasystem
fonction elle-même, pas un "appel système" . Le dernier que vous ne pouvez pas éviter, mais le premier que vous pouvez certainement. Ça a du sens maintenant!/proc/PID
kill 0
/proc
/proc
ps
top
lsof
ne fonctionnera probablement pas - et si cela pourrait ne pas être un problème pour un système de production. Mais il est (théoriquement) possible qu'il n'ait jamais été monté (bien que cela puisse empêcher le système de revenir à un état normal), il est certainement possible qu'il soit démonté (je l'ai testé 1), et je pense qu'il n'y a aucune garantie qu'elle existera (c'est-à-dire qu'elle n'est pas requise par POSIX). Et, à moins que le système ne soit complètement arrosé,kill
cela fonctionnera./proc
nécessite la lecture du répertoire racine pour trouver le/proc
système de fichiers. Cela est vrai pour toute tentative d'accéder à tout fichier par un chemin absolu, y compris les choses dans/bin
,/etc
et/dev
. Cela se produit si souvent que le répertoire racine est sûrement mis en cache dans la mémoire pendant toute la durée de vie (disponibilité) du système, donc cette étape peut être effectuée sans aucune E / S disque. Et, une fois que vous avez l'inode de/proc
, tout ce qui se passe est en mémoire./proc
? Avecstat
,open
,readdir
, etc., qui sont le système natif appelle tout autant quekill
.La question parle d'un processus en cours. Ceci est une phrase glissante. Si vous voulez réellement tester si le processus est en cours d'exécution (c'est-à-dire dans la file d'attente d'exécution; peut-être le processus en cours sur un processeur; pas en veille, en attente ou arrêté), vous devrez peut-être faire et lire la sortie , ou regarder . Mais je ne vois aucun indice dans votre question ou vos commentaires que cela vous préoccupe.
ps PID
/proc/PID/stat
L'éléphant dans la pièce, cependant, est qu'un processus zombie 2 peut être difficile à distinguer d'un processus qui est bien vivant.
kill 0
fonctionne sur un zombie, et existe. Vous pouvez identifier les zombies avec les techniques énumérées dans le paragraphe précédent (faire et lire la sortie, ou regarder ). Mon très rapide et les tests occasionnels (c. -à- pas très approfondie) suggère que vous pouvez aussi le faire en faisant une ou sur , ou - ceux - ci échouera sur les zombies. (Cependant, ils échoueront également sur les processus que vous ne possédez pas.)/proc/PID
ps PID
/proc/PID/stat
readlink
lstat
/proc/PID/cwd
/proc/PID/root
/proc/PID/exe
____________
1 si l' option
-f
( f orce) ne fonctionne pas, essayez-l
( l azy).2 c'est-à-dire un processus qui s'est terminé / est mort / a pris fin, mais dont le parent n'a pas encore fait a
wait
.la source
kill(2)
page de manuel indique directement le comportement que vous avez signalé, mais laperlfunc
page de manuel le fait. Je vais envoyer un courriel à Michael Kerrisk pour voir ce qu'il a à dire sur la page de manuel du système.kill(2)
concernant les autorisations pour "envoyer" le signal 0.kill(2)
page de manuel (je ne la vois pas encore en ligne): "Si sig vaut 0, aucun signal n'est envoyé, mais des vérifications d'existence et de permission sont toujours effectuées; cela peut être utilisé pour vérifier l'existence d'un ID de processus ou ID de groupe de processus que l'appelant est autorisé à signaler. "