Comment puis-je déterminer si un processus est en cours d'exécution ou non, puis qu'un script bash exécute des tâches en fonction de cette condition?
Par exemple:
si le processus
abc
est en cours, faites ceciSi cela ne fonctionne pas, faites-le.
Comment puis-je déterminer si un processus est en cours d'exécution ou non, puis qu'un script bash exécute des tâches en fonction de cette condition?
Par exemple:
si le processus abc
est en cours, faites ceci
Si cela ne fonctionne pas, faites-le.
Réponses:
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
/dev/null
: "/ dev / null redirige la sortie standard de la commande vers le périphérique null, qui est un périphérique spécial qui rejette les informations qui y sont écrites" ... using 0
redirige la sortie de la commande vers un fichier appelé 0
. Dans ce cas, je vous conseillerais de vous familiariser davantage avec le logiciel > /dev/null
. Vous le verrez partout car il s’agit du moyen standard / approprié de supprimer la sortie.
-x
paramètre à pgrep
afin qu'il recherche l'application exacte ou sinon, il obtiendra une erreur fausse s'il trouve la même chaîne dans le nom d'une autre application. Je viens de passer 1 heure pour le découvrir.
! pgrep
Toute solution qui utilise quelque chose comme ps aux | grep abc
ou qui pgrep abc
est défectueux.
Comme 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 contenant 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 toujours pas un 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 la FAQ Bash 45 pour d'autres moyens de verrouillage.
pgrep
ou ps
est parfaitement adéquat et votre approche semble exagérée. Si vous écrivez un script destiné au public, vous devez l’écrire de la manière la plus sûre possible.
rm
commande est exécutée. Donc, tant qu'il se termine après que le piège a été mis, le verrou devrait être parti.
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:
Bash Scripting :: Comparaisons de chaînes
Manuels Ubuntu pgrep
pgrep
a la même "caractéristique" de limite de 15 caractères mentionnée précédemment, ainsi, par exemple pgrep gnome-power-manager
, elle échouerait également
-x
option de pgrep : "Ne faites correspondre que les processus dont le nom (ou la ligne de commande si -f est spécifié) correspond exactement au modèle."
J'ai l'habitude d'avoir un pidof -x $(basename $0)
sur mes scripts pour vérifier s'il est déjà en cours d'exécution.
Riffing sur 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 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 à son tour une ps -ef | grep
approche:
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
La première chose qui me vienne à l’esprit pour votre problème:
ps aux | grep -i abc
montrera les détails du processus s’il fonctionne. 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, c'est-à-dire des détails sur le processus créé par cette commande grep. Prenez donc soin de cela.
Cela devrait faire comme un simple bidouillage. Mettez-le dans le script bash et voyez si c'est utile.
Utilisant 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
## 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 &)
Remarque : pgrep -x lxpanel
ou pidof lxpanel
indique toujours que le lxpanel
logiciel est en cours d'exécution, même s'il est obsolète (zombie); afin d'obtenir un processus en vie, nous devons utiliser ps
etgrep
Depuis le 23 septembre 2016, pgrep semble avoir besoin de l'option "-x" pour que le script de muru fonctionne.
#!/bin/bash
if pgrep -x "conky" > /dev/null 2>&1
then
echo "conky running already"
else
echo "now starting conky"
conky
fi
exit 0
J'ai essayé et testé le script ci-dessus sur une machine Ubuntu 16.04.1. Prendre plaisir!
#!/bin/bash
while [ true ]; do # Endless loop.
pid=`pgrep -x ${1}` # Get a pid.
if [ -z $pid ]; then # If there is none,
${1} & # Start Param to background.
else
sleep 60 # Else wait.
fi
done
zombie
processus '(pas ce que je qualifierais de processus «en cours»). Une liste complète de ce que lesSTAT
valeurs de colonne, dans le résultat deps
, indiquent, est ici pour ceux qui sont enclins à écrire une réponse qui tient compte de cela ou à éditer la leur