Dans un script bash, je veux faire ce qui suit (en pseudo-code):
if [ a process exists with $PID ]; then
kill $PID
fi
Quelle est l'expression appropriée pour l'instruction conditionnelle?
Pour vérifier l'existence d'un processus, utilisez
kill -0 $pid
Mais comme @unwind l'a dit, si vous voulez le tuer de toute façon,
kill $pid
ou vous aurez une condition de course.
Si vous souhaitez ignorer la sortie de 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
kill
est quelque peu mal nommé en ce sens qu'il ne tue pas nécessairement le processus. Il envoie simplement un signal au processus.kill $PID
équivaut àkill -15 $PID
, qui envoie le signal 15, SIGTERM au processus, qui est une instruction pour terminer. Il n'y a pas de signal 0, c'est une valeur spéciale indiquantkill
simplement de vérifier si un signal pourrait être envoyé au processus, ce qui est dans la plupart des cas plus ou moins équivalent à vérifier s'il existe. Voir linux.die.net/man/2/kill et linux.die.net/man/7/signalkill -0
, en fait, je dois faire ceci:kill -0 25667 ; echo $?
- et ensuite si j'obtiens un0
retour, alors le processus avec ce PID peut être tué; et si le processus PID (disons) n'existe pas, le$?
sera1
, indiquant un échec. Est-ce exact?Le meilleur moyen est:
Le problème avec:
est 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 l'autorisation de le tuer. Par exemple:
et
ont un code de sortie indiscernable (non nul) pour un utilisateur normal, mais le processus d'initialisation (PID 1) est certainement en cours d'exécution.
DISCUSSION
Les réponses concernant les conditions de mise à mort et de race sont exactement correctes si le corps du test est un "kill". Je suis venu chercher le général " comment testez-vous l'existence d'un PID dans bash ".
La méthode / proc est intéressante, mais dans un certain sens brise l'esprit de l'abstraction de la commande "ps", c'est-à-dire que vous n'avez pas besoin d'aller chercher dans / proc parce que si Linus décide d'appeler le fichier "exe" autre chose?
la source
-p
n'est pas nécessaire, du moins dans ce cas.ps $PID
a exactement le même résultat.ou
Dans cette dernière forme,
-o pid=
est un format de sortie pour afficher uniquement la colonne ID de processus sans en-tête. Les guillemets sont nécessaires pour que l'opérateur de chaîne non vide-n
donne un résultat valide.la source
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
ps
options et les fonctionnalités ont tendance à varier entre les plates-formes, de sorte qu'elles ne sont toujours pas entièrement portables.$PID
est vide, alors[ -e /proc/$PID ]
retournera toujours true, puisque le/proc/
répertoire existe toujours.ps
commande avec-p $PID
peut faire ceci:la source
Vous avez deux moyens:
Commençons par rechercher une application spécifique dans mon ordinateur portable:
Tous les exemples recherchent maintenant le PID 3358.
Première manière : exécutez "ps aux" et grep pour le PID dans la deuxième colonne. Dans cet exemple, je recherche Firefox, puis son PID:
Donc votre code sera:
Deuxième méthode : cherchez simplement quelque chose dans le
/proc/$PID
répertoire. J'utilise "exe" dans cet exemple, mais vous pouvez utiliser n'importe quoi d'autre.Donc votre code sera:
BTW: quel est le problème avec
kill -9 $PID || true
?ÉDITER:
Après y avoir réfléchi pendant quelques mois ... (environ 24 ...) l'idée originale que j'ai donnée ici est un joli hack, mais hautement non portable. Bien qu'il enseigne quelques détails d'implémentation de Linux, il ne fonctionnera pas sur Mac, Solaris ou * BSD. Il pourrait même échouer sur les futurs noyaux Linux. Veuillez utiliser "ps" comme décrit dans les autres réponses.
la source
/proc/$PID/exe
n'est pas un fichier ordinaire. Donc,[ -f /proc/$PID/exe ]
retournera toujours unfalse
résultat. Essayez[ -h /proc/$PID/exe ]
.Il semble que tu veux
qui reviendra une fois
$pid
terminé.Sinon, vous pouvez utiliser
pour vérifier si le processus est toujours en vie (c'est plus efficace que
kill -0 $pid
parce qu'il fonctionnera même si vous ne possédez pas le pid).la source
pid 123 is not a child of this shell
Je pense que c'est une mauvaise solution, qui ouvre aux conditions de course. Et si le processus meurt entre votre test et votre appel à tuer? Alors tuer échouera. Alors pourquoi ne pas simplement essayer le kill dans tous les cas, et vérifier sa valeur de retour pour savoir comment cela s'est passé?
la source
kill -9
. Cela tue instantanément le processus, ne lui donnant aucune chance de se nettoyer après lui-même. Utilisez plutôtkill
ce qui équivaut àkill -15
. Si cela ne fonctionne pas, vous devriez savoir pourquoi, et uniquement en dernier recourskill -9
.ici, je stocke le PID dans un fichier appelé .pid (qui est un peu comme / run / ...) et n'exécute le script que s'il n'est pas déjà exécuté.
note: il y a une condition de concurrence car elle ne vérifie pas comment ce pid est appelé. si le système est redémarré et que .pid existe mais est utilisé par une autre application, cela peut entraîner des «conséquences imprévues».
la source
Par exemple, dans GNU / Linux, vous pouvez utiliser:
Ou quelque chose comme
et cela vous montre le nom de l'application, juste le nom sans ID.
la source
pidof
ne renvoie pas de nombre négatif, car un PID négatif n'a aucun sens, et vous ne pouvez pas tuerinit
, donc votre conditionnel n'a aucun sens (et de plus, vous devrez échapper à>
pour l'empêcher d'effectuer une redirection). Vous voulez vérifier un résultat vide, mais bien sûr, comme tout outil décent,pidof
définit un code de sortie pour vous dire si cela a fonctionné, donc la bonne solution estif Pid=$(pidof 'process_name'); then ...
ou (si vous n'aurez pas besoin de la valeurPid
plus tard) simplementif pidof 'process_name'; then...
pidof
exemple est plein de malentendus sur le fonctionnement de bashtest
. gnu.org/software/bash/manual/html_node/…le code ci-dessous vérifie si mon processus est en cours d'exécution, si c'est le cas, ne faites rien.
vérifions les nouveaux messages d'Amazon SQS toutes les heures uniquement et uniquement si le processus n'est pas en cours d'exécution.
la source