Puis-je créer une ligne de commande bash qui n'exécute qu'une certaine commande si le processus n'est pas déjà en cours d'exécution (en arrière-plan)?
Comment vérifier * si une commande est déjà en cours d'exécution?
(afin que je puisse ajouter la commande suivante &&
entre eux afin que la suivante s'exécute uniquement si la première est vraie).
*: tester, déterminer, découvrir, découvrir
ps -ef | grep -v grep | grep "process_name" || run_command_here
pgrep "process_name"
au lieu deps | grep | grep
Réponses:
Utilisez daemontools . Vous pouvez utiliser
svok
pour vérifier si un processus service / démon / arrière-plan est en cours d'exécution.Pour d'autres méthodes, voir:
la source
J'ai utilisé cette technique de temps en temps:
Avant
pgrep
cela se faisait de cette façon:exemple
Le bit avec le
[p]
fait en sorte que legrep
ne se retrouve pas en conséquence.la source
Cela peut être délicat, car vous pouvez avoir des instances distinctes du même processus qui vivent indépendamment. Par exemple, des serveurs écoutant sur différents ports ou des services fonctionnant sous différents utilisateurs. Afin de faire la distinction entre ces instances, vous devez attribuer à chacune d'entre elles une balise unique. La balise est souvent un fichier, mais elle peut être une socket locale dans l'espace de noms abstrait, un port TCP, etc. - n'importe quel identifiant unique fera l'affaire. Lorsque la balise est un fichier, il peut s'agir d'un fichier standard contenant un ID de processus (un pidfile), ou un canal ou socket nommé que le fichier écoute, etc. Idéalement, la balise est un point de terminaison de communication qui permet aux clients de se connecter à ce processus.
Chacun de ces différents types de balises entraîne une manière différente de vérifier si l'instance que vous recherchez est opérationnelle. Par exemple, avec un socket de fichier local, essayez de vous y connecter et démarrez le processus s'il n'y a pas de processus d'écoute sur ce socket. Si la balise est un fichier pid, vérifiez s'il existe un processus avec cet ID de processus, mais attention à ce qu'il soit fragile, car si le processus est mort, il peut y avoir un processus indépendant qui a réutilisé son ID. Gardez à l'esprit que si deux clients tentent d'atteindre le processus dans un court laps de temps, ils pourraient tous deux constater que le processus n'existe pas et tous les deux tenter de le démarrer; une protection adéquate contre cette condition de concurrence peut être délicate.
Il est plus facile de gérer les instances lorsqu'elles sont toutes démarrées par le même processus de superviseur, et ce processus de superviseur détecte quand les instances meurent et réagit en conséquence. De nombreux programmes de surveillance des services peuvent le faire.
Si le programme ne répond pas sur un point de terminaison de communication connu et qu'il n'est pas géré par un programme superviseur, la balise du pauvre est un fichier pid: un fichier contenant l'ID du processus. Lorsque vous démarrez le processus, écrivez le pid dans un fichier avec un nom préarrangé. Lorsque vous avez besoin que le processus existe, lisez le fichier pid et voyez s'il existe un processus avec ce pid. Lorsque vous tuez le processus, effacez le fichier pid. Le problème le plus important avec un fichier pid non supervisé est que si le processus meurt, son pid peut être réutilisé par un processus non lié. Vous devez au moins vérifier le nom du processus ou l'exécutable du processus pour vous assurer que vous parlez au bon processus. De nombreuses variantes Unix ont une commande pgrep :
pgrep SOMENAME
répertorie les processus dont le nom contient SOMENAME en tant que sous-chaîne, avec des options supplémentaires pour limiter à un utilisateur particulier, pour exiger une correspondance exacte, pour changer laquelle des différentes notions possibles de «nom de processus» est utilisée, etc.la source
Vous pouvez utiliser cette approche:
la source
Autres options:
pgrep -xq processname
ps -eo comm= | sed 's|.*/||' | grep -xq processname
sed 's|.*/||'
supprime les parties dirname sous OS XSous GNU / Linux, les
ps -o comm
noms de commande sont tronqués à 15 caractèrespgrep
etps -C
ne correspondent qu'aux 15 premiers caractères.ps -C
(correspondre aux noms de commande) n'est pas pris en charge sous OS X.Sous OS X,
ps -o comm
imprime les chemins absolus des commandes etps -co comm
n'imprime que les noms des commandes. Dans GNU,ps -o comm
imprime uniquement les noms de commandes et-c
a une signification différente.Pgrep d'OS X n'inclut pas les processus ancêtres (comme bash, Terminal ou launchd) sans
-a
. Pgrep de GNU les inclut par défaut et il ne les prend pas en charge-a
.grep -x
etpgrep -x
n'implique pas-F
, donc utilisez-Fx
si le nom du processus peut contenir des caractères regex.la source
Je suis désolé mais toutes ces solutions ne prennent pas en charge contab car la même ligne de commande apparaîtra deux fois dans le résultat 'ps'.
Voici donc le mien:
la source
cron
emploi?Avec Bash
Remarque: - supprimez
echo
si la sortie semble correcte.la source
Je vais vous expliquer le cas où vous exécutez la commande dans beckgreoud. Le "$!" enregistrer le PID du dernier processus d'arrière-plan. Ainsi, vous pouvez l'utiliser pour le trouver dans les tableaux de processus suivant les réponses ci-dessus:
La commande intégrée "jobs" - essayez ceci:
Concernant l'option "&&"
Au lieu de &&, utilisez la commande wait. Dans l'exemple suivant, myproc2 ne s'exécutera pas tant que myproc1 n'aura pas terminé:
la source
Obtenez l'état de votre processus:
ps -lp $(pgrep <YOUR_PROCESS_NAME>) | tail -1 | awk '{print $11}'
Référence:
Par exemple, je l'ai utilisé pour jouer ou suspendre conditionnellement mon processus sox sur une session tmux:
la source
Vous pouvez l'utiliser dans un script:
la source