Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

v

17 réponses
Avatar
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

10 réponses

1 2
Avatar
Olivier Miakinen
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
Avatar
denist
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
Avatar
Che Averell
denist écrit :

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,
Avatar
Gilles Pion
Ref: de 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.




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
Avatar
Che Averell
Gilles Pion écrit :
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...
Avatar
Gilles Pion
Ref: de Che Averell

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
Avatar
Olivier Miakinen
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.
Avatar
Gilles Pion
Ref: <4d99f9e1$ de Olivier Miakinen
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
Avatar
Stephane CHAZELAS
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
Avatar
xavier
Che Averell wrote:

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)
1 2