J'ai besoin d'un indépendant de la plateforme (Unix/Linux|OSX) shell/bash de commande qui permettra de déterminer si un processus est en cours d'exécution. par exemple, mysqld
, httpd
...
Quelle est la façon la plus simple/commande pour le faire?
Réponses
Trop de publicités?Alors qu' pidof
et pgrep
sont d'excellents outils pour la détermination de ce qui est en cours d'exécution, ils sont tous les deux, malheureusement, pas disponible sur certains systèmes d'exploitation. Un certain fail safe serait d'utiliser la syntaxe suivante: ps cax | grep command
La sortie sur Gentoo Linux:
14484 ? S 0:00 apache2 14667 ? S 0:00 apache2 19620 ? Sl 0:00 apache2 21132 ? Ss 0:04 apache2
La sortie sur OS X:
42582 ?? Z 0:00.00 (smbclient) 46529 ?? Z 0:00.00 (smbclient) 46539 ?? Z 0:00.00 (smbclient) 46547 ?? Z 0:00.00 (smbclient) 46586 ?? Z 0:00.00 (smbclient) 46594 ?? Z 0:00.00 (smbclient)
Sur Linux et OS X, grep renvoie un code de sortie de sorte qu'il est facile de vérifier si le processus a été trouvé ou pas:
#!/bin/bash
ps cax | grep httpd > /dev/null
if [ $? -eq 0 ]; then
echo "Process is running."
else
echo "Process is not running."
fi
En outre, si vous voulez que la liste des Pid, vous pouvez facilement grep pour ceux aussi bien:
ps cax | grep httpd | grep -o '^[ ]*[0-9]*'
Dont la sortie est la même chose sur Linux et OS X:
3519 3521 3523 3524
La sortie de la suivante est une chaîne vide, cette approche sécuritaire pour les processus qui ne sont pas en cours d'exécution:
echo ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*'
Cette approche est bien adaptée pour l'écriture d'une simple chaîne de caractères vide de test, alors même itération à travers la découverte des Pid.
#!/bin/bash
PROCESS=$1
PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*[0-9]*'`
if [ -z "$PIDS" ]; then
echo "Process not running." 1>&2
exit 1
else
for PID in $PIDS; do
echo $PID
done
fi
Vous pouvez le tester en l'enregistrant dans un fichier (nommé "course") avec des autorisations d'exécution (chmod +x) et de l'exécuter avec un paramètre: ./running "httpd"
#!/bin/bash
ps cax | grep httpd
if [ $? -eq 0 ]; then
echo "Process is running."
else
echo "Process is not running."
fi
ATTENTION!!!
Veuillez garder à l'esprit que vous êtes tout simplement l'analyse de la sortie de l' ps ax
ce qui signifie que, comme on le voit dans le Linux de sortie, il n'est pas simplement la mise en correspondance sur les processus, mais également les arguments passés au programme. Je recommande fortement d'être aussi précis que possible lors de l'utilisation de cette méthode (par exemple, ./running "mysql"
correspond aussi à la 'mysqld' processus). Je recommande fortement d'utiliser which
pour vérifier la présence d'un chemin d'accès complet si possible.
Références:
Vous DEVEZ connaître le PID !
Trouver un processus en essayant de faire une sorte de reconnaissance de formes sur le processus d'arguments (comme pgrep "mysqld"
) est une stratégie vouée à l'échec tôt ou tard. Que faire si vous avez deux mysqld en cours d'exécution? Oubliez cette approche. Vous POUVEZ l'obtenir droite temporairement et il PEUT travailler pour un an ou deux, mais ensuite il se passe quelque chose que vous n'avez pas pensé.
L'id de processus (pid) est vraiment unique.
Rangez toujours le pid lorsque vous lancez quelque chose dans le fond. En Bash cela peut être fait avec l' $!
Bash variable. Vous vous épargnerez beaucoup de problèmes en le faisant.
Comment faire pour déterminer si le processus est en cours d'exécution (par pid)
Alors maintenant, la question devient comment savoir si le pid est en cours d'exécution.
Il suffit de faire:
ps -o pid= -p <pid>
C'est POSIX et donc portable. Il sera de retour le pid si le processus est en cours d'exécution ou ne retournent rien si le processus n'est pas en cours d'exécution. Strictement parlant, la commande retourne une colonne unique, l' pid
, mais depuis que nous avons donné qu'un vain titre de l'en-tête (les trucs qui précède immédiatement le signe égal) et c'est la seule colonne demandé, puis la commande ps ne sera pas utiliser l'en-tête. Qui est ce que nous voulons, car il rend l'analyse plus facile.
Cela fonctionne sur Linux, BSD, Solaris, etc.
Une autre stratégie serait de tester sur la sortie de la valeur de ce qui précède ps
commande. Il doit être égal à zéro si le processus est en cours d'exécution et non nulle si elle n'est pas. POSIX spec dit qu' ps
doit quitter >0 si une erreur a eu lieu, mais il est clair pour moi ce que constitue une "une erreur". Donc je ne suis pas personnellement en utilisant cette stratégie, bien que je suis assez sûr que ça va fonctionner aussi bien sur tous les Unix/Linux.
Sur la plupart des distributions Linux, vous pouvez utiliser pidof
(8).
Il permet d'imprimer les id de toutes les instances en cours d'exécution de processus spécifiés, ou rien si il n'y a pas d'instances en cours d'exécution.
Par exemple, sur mon système (j'ai quatre instances de bash
et une instance de remmina
d'exécution):
$ pidof bash remmina
6148 6147 6144 5603 21598
Sur les autres Unix, pgrep
, ou une combinaison d' ps
et grep
permettra de réaliser la même chose, comme d'autres l'ont à juste titre souligné.
Cela devrait fonctionner sur la plupart des saveurs de Unix, BSD et Linux:
PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep
Testé sur:
- SunOS 5.10 [d'Où l'
PATH=...
] - Linux 2.6.32 (CentOS)
- Linux 3.0.0 (Ubuntu)
- Darwin 11.2.0
- FreeBSD 9.0-STABLE
- Red Hat Enterprise Linux ES 4
- Red Hat Enterprise Linux Server version 5
Juste un petit ajout: si vous ajoutez l' -c
drapeau pour le ps, vous n'avez pas besoin de supprimer la ligne contenant la commande grep processus avec grep -v
par la suite. I. e.
ps acux | grep cron
est tous la saisie vous aurez besoin sur un bsd-ish système (cela comprend MacOSX), Vous pouvez laisser l' -u
suite si vous avez besoin de moins d'informations.
Sur un système où la génétique de la native ps
point de commandement de retour à SysV, vous pouvez utiliser
ps -e |grep cron
ou
ps -el |grep cron
pour une liste contenant plus que juste le pid et le nom du processus. Bien sûr vous pouvez sélectionner les champs à imprimer à l'aide de l' -o <field,field,...>
option.