v

Le
denist
Bonjour,

J'ai quelques scripts que j'ai bricolés, lancés via cron.
J'aimerais ajouter à une vérification, si le script est déjà lancé, ça
quitte silencieusement. Comme certaines étapes du script sont longues
(compressions de données par exemple), je souhaite éviter que la tâche
cron suivante ne relance le même script si le précédent est toujours en
cours.

Merci d'avance
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Olivier Miakinen
Le #23257221
Bonjour,

Le 04/04/2011 16:11, denist a écrit :

J'ai quelques scripts que j'ai bricolés, lancés via cron.
J'aimerais ajouter à une vérification, si le script est déjà lancé, ça
quitte silencieusement. Comme certaines étapes du script sont longues
(compressions de données par exemple), je souhaite éviter que la tâche
cron suivante ne relance le même script si le précédent est toujours en
cours.



As-tu essayé avec la commande ps ?

Cordialement,
--
Olivier Miakinen
denist
Le #23257211
Le Mon, 04 Apr 2011 16:37:54 +0200, Olivier Miakinen a écrit :

Bonjour,

Le 04/04/2011 16:11, denist a écrit :

J'ai quelques scripts que j'ai bricolés, lancés via cron. J'aimerais
ajouter à une vérification, si le script est déjà lancé, ça quitte
silencieusement. Comme certaines étapes du script sont longues
(compressions de données par exemple), je souhaite éviter que la tâche
cron suivante ne relance le même script si le précédent est toujours en
cours.



As-tu essayé avec la commande ps ?

Cordialement,



Bonjour

Oui j'y ai pensé, voici mon essai. Ça semble fonctionner mais je ne sais
pas si c'est propre. Je pensais qu'il y avait une commande prévue.

#!/bin/bash
#/usr/local/bin/mon_script
$SCRIPT=mon_script
ps auwx | grep -v grep | grep $SCRIPT >/dev/null
if [ "$?" = "0" ]
then
echo -e "Au moins un processus est déjà lancé."
else
echo -e "Lancement..."
[le reste du script]
fi
Che Averell
Le #23257481
denist
Yop yop,

Oui j'y ai pensé, voici mon essai. Ça semble fonctionner mais je ne sais
pas si c'est propre. Je pensais qu'il y avait une commande prévue.



Non, c'est pas propre. La commande prévue pour ce genre de trucs est
lockf(1) sur un BSD ou flock(1) sur un linux. Je ne sais pas s'il y a
une version posix de ces utilitaires.

Regarder le man pour savoir comment ça s'utilise. Il faut juste faire
attention quand on tue le script qui utilise ces commandes et de virer
le fichier de lock, sinon le risque que le script ne se relance jamais
est assez élevé (ne me demandez pas comment je le sais).

cdlt,
Gilles Pion
Le #23257841
Ref:
Bonjour,

J'ai quelques scripts que j'ai bricolés, lancés via cron.
J'aimerais ajouter à une vérification, si le script est déjà lancé, ça
quitte silencieusement. Comme certaines étapes du script sont longues
(compressions de données par exemple), je souhaite éviter que la tâche
cron suivante ne relance le même script si le précédent est toujours en
cours.




pour ce genre de besoin, j'utilise l'approche suivante

progname="<nom du script ici>"
piddir=/var/tmp # la coutume est d'utiliser /var/run
# mais faut être root

pidfile=$piddir/$progname # va contenir le PID du script en exécution

# noter que le "kill -0" n'est pas "destructeur"
if -f $pidfile && kill -0 $(<$pidfile) ; then
# on a détecté que le script s'exécute,
echo >&2 "$progname "déja lancé - abort"
# (supprimer la ligne ci dessous pour quitter "silencieusement")
exit 1
fi
# la voie est libre
echo "$$" >$pidfile # d'abord s'enregistrer
# destruction automatique du fichier à la fin
trap "rm -f $pidfile" EXIT
# la partie "utile" du script vient ci-dessous




--> vérifier que la syntaxe $(<pidfile) marche en bash (j'ai plutôt l'habitude
du korn), et sinon, remplacer par `cat $pidfile`.
--
Gilles Pion
Che Averell
Le #23257881
Gilles Pion
pour ce genre de besoin, j'utilise l'approche suivante



<snip>

Oui, mais non. Globalement, ça marche, mais comme la vérification et
la pose du lock n'est pas atomique, si les deux programmes sont lancés
en même temps il est possible de lancer deux fois le programme
simultanément (en gros quand les deux programmes vont regarder que le
fichiers existe avant que l'un ou l'autre ne le créé).

Et comme la loi de Brown[1] dit que si ça peut pêter, alors ça va
pêter, je déconseille fortement de faire ça, même si la plupart du
temps ça marche. La même loi dit que quand ça va pêter, ça va être au
pire moment...

[1] Brown, c'est le type qui disait que Murphy était optimiste...
Gilles Pion
Le #23257871
Ref:

Oui, mais non. Globalement, ça marche, mais comme la vérification et
la pose du lock n'est pas atomique, si les deux programmes sont lancés
en même temps il est possible de lancer deux fois le programme
simultanément (en gros quand les deux programmes vont regarder que le
fichiers existe avant que l'un ou l'autre ne le créé).



De la question initiale, ou il est question de cron, on peut, sans trop de
risque de se tromper, déduire que le script en question est lancé par une unique
crontab à intervalles réguliers, et dans ce cas pas de risque de provoquer ce
genre de "collision" (qui implique deux exécutions *strictements* simultanées).
--
Gilles Pion
Olivier Miakinen
Le #23257961
Bonjour,

Le 04/04/2011 18:51, Che Averell a écrit :

[...] si les deux programmes sont lancés en même temps [...]



Vu le contexte (tâches lancées par cron, durée d'exécution possiblement
plus longue que l'intervalle entre deux cron successifs), ça ne devrait
pas arriver. Cela dit, dans l'absolu tu as raison : si un lock atomique
existe, autant l'utiliser.
Gilles Pion
Le #23258011
Ref:
Bonjour,

Le 04/04/2011 18:51, Che Averell a écrit :

[...] si les deux programmes sont lancés en même temps [...]



Vu le contexte (tâches lancées par cron, durée d'exécution possiblement
plus longue que l'intervalle entre deux cron successifs), ça ne devrait
pas arriver. Cela dit, dans l'absolu tu as raison : si un lock atomique
existe, autant l'utiliser.



La version ci dessous devrait j'espère satisfaire tout le monde (le noclobber
assurant l'unicité via l'atomicité de "creat")

#! /bin/bash

progname="runalone"
piddir=/var/tmp # la coutume est d'utiliser /var/run
# mais faut être root

pidfile=${piddir}/${progname}.pid # va contenir le PID du script en exécution

shellflags=$- # sauvegarder la configuration des flags du shell
set -o noclobber
#
# "2>/dev/null" pour masquer le message d'erreur
# en cas de fichier existant
#
{ echo "$$" >$pidfile ; } 2>/dev/null || {
# déja en cours d'exécution
echo >&2 "exécution de $progname détectée"
exit 1
}
set -$shellflags # rétablir l'état des flags

# destruction automatique du fichier à la fin
trap "rm -f $pidfile" EXIT
# la partie "utile" du script vient ci-dessous
--
Gilles Pion
Stephane CHAZELAS
Le #23258501
2011-04-04, 09:11(-05), denist:
[...]
J'ai quelques scripts que j'ai bricolés, lancés via cron.
J'aimerais ajouter à une vérification, si le script est déjà lancé, ça
quitte silencieusement. Comme certaines étapes du script sont longues
(compressions de données par exemple), je souhaite éviter que la tâche
cron suivante ne relance le même script si le précédent est toujours en
cours.


[...]

Sur certains systemes, on trouve un start-stop-daemon qui peut
aider:

$ start-stop-daemon --pidfile /tmp/sleep.pid --make-pidfile --exec /bin/sleep --start -- 100 &
$ start-stop-daemon --pidfile /tmp/sleep.pid --make-pidfile --exec /bin/sleep --start -- 1
/bin/sleep already running.

--
Stephane
xavier
Le #23258911
Che Averell
Non, c'est pas propre. La commande prévue pour ce genre de trucs est
lockf(1) sur un BSD ou flock(1) sur un linux. Je ne sais pas s'il y a
une version posix de ces utilitaires.



Pour ça, je préfère la commande lockfile(1) du package procmail (je ne
l'installe d'ailleurs que pour ça, je hais la syntaxe de procmailrc).

C'est nettement plus facile à insérer dans un script que lockf(1) qui
demande une commande en argument et l'éxécute.

Ex (en sh POSIX)
LOCKFILE="/usr/local/bin/lockfile"
MYLOCK="/var/run/myscript/lock"
trap "rm -f $MYLOCK" 0 1 2 3 15
# Initialisations non-critiques
# ...
if [ -x $LOCKFILE ]; then
$LOCKFILE -1 -r 0 $MYLOCK # Essaie toutes les secondes, 10 fois
if [$? -eq 0 ]; then
#... des tas de choses
else
echo "Stale lock file ?"
fi
rm -f $MYLOCK
fi

Regarder le man pour savoir comment ça s'utilise. Il faut juste faire
attention quand on tue le script qui utilise ces commandes et de virer
le fichier de lock, sinon le risque que le script ne se relance jamais
est assez élevé (ne me demandez pas comment je le sais).



Comme indiqué ci-dessus, trap est notre ami. Been there, done that :-)


--
XAv
In your pomp and all your glory you're a poorer man than me,
as you lick the boots of death born out of fear.
(Jethro Tull)
Publicité
Poster une réponse
Anonyme