Comment puis-je déterminer si un processus est en cours d'exécution ou non, puis demander à un script bash d'exécuter certaines tâches en fonction de cette condition?
Par exemple:
si le processus abc
est en cours d'exécution, procédez comme suit.
si cela ne fonctionne pas, faites-le.
Un script bash pour faire quelque chose comme ça pourrait ressembler à ça:
#!/bin/bash
# Check if gedit is running
# -x flag only match processes whose name (or command line if -f is
# specified) exactly match the pattern.
if pgrep -x "gedit" > /dev/null
then
echo "Running"
else
echo "Stopped"
fi
Ce script vérifie simplement si le programme "gedit" est en cours d'exécution.
Ou vous pouvez seulement vérifier si le programme ne fonctionne pas comme ceci:
if ! pgrep -x "gedit" > /dev/null
then
echo "Stopped"
fi
Toute solution utilisant quelque chose comme ps aux | grep abc
ou pgrep abc
est défectueuse.
Étant donné que vous ne vérifiez pas si un processus spécifique est en cours d'exécution, vous vérifiez si des processus en cours d'exécution correspondent à abc
. Tout utilisateur peut facilement créer et exécuter un exécutable nommé abc
(ou qui contient abc
quelque part dans son nom ou ses arguments), ce qui provoque un faux positif pour votre test. Il existe différentes options que vous pouvez appliquer à ps
, grep
et pgrep
pour affiner la recherche, mais vous n’obtiendrez toujours pas de test fiable.
Cela dépend de ce que vous avez besoin du test.
C'est à cela que servent init et upstart. Ils vont démarrer le service et s'assurer que son pid est stocké dans un pidfile. Essayez de redémarrer le service (via init ou upstart) et il vérifiera le pidfile, et le démarrera s'il n'est pas là ou annulera s'il est déjà en cours d'exécution. Ce n'est toujours pas fiable à 100%, mais c'est aussi proche que possible.
Voir Comment puis-je vérifier si mon serveur de jeu est toujours en cours d'exécution ... pour d'autres solutions.
Dans ce cas, utilisez un lockfile ou un lockdir. Par exemple.
#!/usr/bin/env bash
if ! mkdir /tmp/abc.lock; then
printf "Failed to acquire lock.\n" >&2
exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT # remove the lockdir on exit
# rest of script ...
Voir Bash FAQ 45 pour d'autres moyens de verrouillage.
C'est ce que j'utilise:
#!/bin/bash
#check if abc is running
if pgrep abc >/dev/null 2>&1
then
# abc is running
else
# abc is not running
fi
En clair:: si 'pgrep' renvoie 0, le processus est en cours d'exécution, sinon ce n'est pas le cas.
Lecture connexe:
Script Bash :: Comparaisons de chaînes
Manuels Ubuntu pgrep
J'ai généralement un pidof -x $(basename $0)
sur mes scripts pour vérifier s'il est déjà en cours d'exécution.
Pour suivre l’idée de @rommel-cid, vous pouvez utiliser pidof
avec le || (||) pour exécuter une commande si le processus n'existe pas et && pour exécuter quelque chose si le processus existe, créant ainsi un conditionnel rapide if/then/else. Par exemple, voici un exemple avec un processus en cours d'exécution (mon navigateur chrome, dont le nom de processus est "chrome") et un test pour un processus inexistant. J'ai supprimé la sortie standard en utilisant 1>/dev/null pour qu'elle ne soit pas imprimée:
$ (pidof chrome 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run instea\
d"
its running? ok, so am i then
$ (pidof nosuchprocess 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run\
instead"
it's not running? ok i'll run instead
$
Aucune des solutions "simples" n'a fonctionné pour moi car le binaire que je dois vérifier n'est pas installé à l'échelle du système. Je dois donc vérifier avec le chemin, ce qui nécessite l'utilisation de l'approche ps -ef | grep
:
app="$_sdir/Logic 1.2.18 (64-bit)/Logic"
app_pid=`ps -ef | grep "$app" | awk '{print $2}'`
if `ps -p $app_pid > /dev/null`; then
echo "An instance of logic analyzer is appear to be running."
echo "Not starting another instance."
exit 5
else
Nohup "$app" &> /dev/null &
fi
## bash
## function to check if a process is alive and running:
_isRunning() {
ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1
}
## example 1: checking if "gedit" is running
if _isRunning gedit; then
echo "gedit is running"
else
echo "gedit is not running"
fi
## example 2: start lxpanel if it is not there
if ! _isRunning lxpanel; then
lxpanel &
fi
## or
_isRunning lxpanel || (lxpanel &)
Note: pgrep -x lxpanel
ou pidof lxpanel
signale toujours que lxpanel
est en cours d'exécution même lorsqu'il est obsolète (zombie); donc pour obtenir un processus actif, nous devons utiliser ps
et grep
La première chose qui m'est venue à l’esprit pour votre problème:ps aux | grep -i abc
affichera les détails du processus s’il est exécuté. Vous pouvez faire correspondre le nombre de lignes ou le temps pour lequel il est exécuté et le comparer à zéro ou à toute autre manipulation. Lorsque vous exécutez la commande ci-dessus, il vous montrera au moins une ligne de sortie, à savoir des détails sur le processus créé par cette commande grep. Prenez donc soin de cela.
Cela devrait faire office de simple bidouillage. Mettez-le dans le script bash et voyez si c'est utile.
Utiliser start-stop-daemon
:
/sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2
Cela fonctionne comme utilisateur normal.
J'ai trouvé que la réponse acceptée postée par @John Vrbanac ne fonctionnait pas pour moi et que la réponse postée par @geirha ne répondait pas à la question initiale.
La solution de John Vrbanac n'a pas fonctionné pour vérifier si un processus PHP fonctionnait ou non pour moi, j'utilise CentOS 7.
La réponse de @ geirha s'assure seulement qu'une instance n'est pas déjà en cours d'exécution avant d'en démarrer une autre. Ce n'était pas la question initiale, la question initiale était de vérifier si un processus est en cours d'exécution ou non.
Voici ce qui a fonctionné pour moi:
Supposons que mon processus comporte la chaîne "Jane" dans son nom de processus. Cela va trouver si c'est en cours d'exécution ou non. Cela fonctionne pour les scripts BASH et PHP.
ps -aux | grep "[J]ane" > /dev/null 2>&1
if [[ "$?" == "0" ]]; then
echo "It's running"
else
echo "It's not running"
fi