138 votes

Quel est le meilleur moyen de s'assurer qu'une seule instance d'un script Bash est en cours d'exécution ?

Quel est le moyen le plus simple/le plus efficace de s'assurer qu'une seule instance d'un script donné est en cours d'exécution - en supposant qu'il s'agisse de Bash sur Linux ?

En ce moment, je le fais :

ps -C script.name.sh > /dev/null 2>&1 || ./script.name.sh

mais il présente plusieurs problèmes :

  1. il met la vérification en dehors de script
  2. il ne me laisse pas exécuter le même script à partir de comptes séparés - ce que j'aimerais parfois.
  3. -C vérifie uniquement les 14 premiers caractères du nom du processus

Bien sûr, je peux écrire ma propre gestion du fichier pidfile, mais je sens qu'il devrait y avoir un moyen simple de le faire.

-2voto

J'ai trouvé un moyen assez simple de gérer "une copie de script par système". Cela ne me permet pas d'exécuter plusieurs copies du script à partir de plusieurs comptes cependant (sur Linux standard qui est).

Solution :

Au début de script, j'ai donné :

pidof -s -o '%PPID' -x $( basename $0 ) > /dev/null 2>&1 && exit

Apparemment pidof fonctionne bien d'une manière qui :

  • il n'a pas de limite sur le nom du programme comme ps -C ...
  • ça ne me demande pas de faire grep -v grep (ou quelque chose de similaire)

Et il ne repose pas sur les lockfiles, ce qui pour moi est une grande victoire, car les relayer signifie que vous devez ajouter la gestion des lockfiles périmés - ce qui n'est pas vraiment compliqué, mais si cela peut être évité - pourquoi pas ?

Quant à la vérification avec "une copie de script par utilisateur en cours d'exécution", j'ai écrit ceci, mais je n'en suis pas très satisfait :

(
    pidof -s -o '%PPID' -x $( basename $0 ) | tr ' ' '\n'
    ps xo pid= | tr -cd '[0-9\n]'
) | sort | uniq -d

et ensuite je vérifie sa sortie - si elle est vide - il n'y a pas de copies du script du même utilisateur.

-3voto

Hamish Downer Points 4086

Voici notre morceau standard. Il peut récupérer le script en mourant sans nettoyer son fichier de verrouillage.

Il écrit l'ID du processus dans le fichier de verrouillage s'il s'exécute normalement. S'il trouve un fichier verrouillé lorsqu'il commence à fonctionner, il lit l'ID du processus dans le fichier verrouillé et vérifie si ce processus existe. Si le processus n'existe pas, il supprime le fichier de verrouillage périmé et poursuit son travail. Et ce n'est que si le fichier de verrouillage existe ET que le processus est toujours en cours d'exécution qu'il se termine. Et il écrit un message lorsqu'il se termine.

# lock to ensure we don't get two copies of the same job
script_name="myscript.sh"
lock="/var/run/${script_name}.pid"
if [[ -e "${lock}" ]]; then
    pid=$(cat ${lock})
    if [[ -e /proc/${pid} ]]; then
        echo "${script_name}: Process ${pid} is still running, exiting."
        exit 1
    else
        # Clean up previous lock file
        rm -f ${lock}
   fi
fi
trap "rm -f ${lock}; exit $?" INT TERM EXIT
# write $$ (PID) to the lock file
echo "$$" > ${lock}

-4voto

ennuikiller Points 28005

Avec votre script :

ps -ef | grep $0 | grep $(whoami)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X