172 lines
6.2 KiB
Plaintext
172 lines
6.2 KiB
Plaintext
|
#!/bin/bash
|
||
|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||
|
|
||
|
function display_help() {
|
||
|
uecho "$scriptname: lancer une suite de commande en respectant une planification de type cron
|
||
|
|
||
|
USAGE
|
||
|
$scriptname [options] /path/to/crontab
|
||
|
|
||
|
Ce script doit normalement être lancé toutes les minutes par une tâche cron. A
|
||
|
chaque lancement, il examine quels scripts doivent être exécutés dans le fichier
|
||
|
crontab spécifié. Ce fichier est composé de lignes d'une des formes suivantes,
|
||
|
qui sont analysées et traitées dans l'ordre:
|
||
|
|
||
|
# commentaire ignoré
|
||
|
var=\"initialiser une variable\"
|
||
|
minutes hours days months dows command [args]
|
||
|
|
||
|
Quelles que soient les lignes qui sont sélectionnées pour le lancement, elles
|
||
|
sont garanties de s'exécuter sériellement dans l'ordre du fichier, d'où le nom
|
||
|
de ce script.
|
||
|
|
||
|
Certaines extensions par rapport à la syntaxe de crontab sont autorisées. Il est
|
||
|
en particulier possible de spécifier plusieurs planifications pour une seule
|
||
|
commande. Par exemple, la ligne suivante permet d'exécuter 'command' toutes les
|
||
|
heures ET à 1h05:
|
||
|
|
||
|
0 * * * *
|
||
|
5 1 * * * command
|
||
|
|
||
|
De plus, il est possible de manipuler les variables de type PATH avec une
|
||
|
syntaxe particulière de l'opérateur d'assignation. Les opérateurs += et %=
|
||
|
utilisent uaddpath(), #= utilise uinspath() et -= utilise udelpath(). Par
|
||
|
exemple, les lignes suivantes ajoutent respectivement /usr/local/nutools puis
|
||
|
enlèvent /opt/rogue au PATH:
|
||
|
|
||
|
PATH+=/usr/local/nutools
|
||
|
PATH-=/opt/rogue
|
||
|
|
||
|
|
||
|
OPTIONS
|
||
|
--install
|
||
|
Installer une planification toutes les minutes de ce script dans la
|
||
|
crontab de l'utilisateur.
|
||
|
--uninstall
|
||
|
Désinstaller la planification toutes les minutes de ce script du crontab
|
||
|
de l'utilisateur.
|
||
|
--lock LOCKFILE
|
||
|
Inscrire dans le fichier spécifié des informations permettant d'éviter
|
||
|
les invocations simultanées de ce script. Si selon ce fichier, le script
|
||
|
tourne depuis plus de $LOCKDELAY heures, un message d'erreur est loggé
|
||
|
et un message d'avertissement est affiché au plus une fois.
|
||
|
Utiliser --lock '' pour désactiver cette fonctionnalité
|
||
|
Par défaut, si ce script est lancé en root, le fichier utilisé pour le
|
||
|
verrouillage est de la forme /var/run/$scriptname/abspath/to/crontab
|
||
|
Si le script est lancé avec un compte utilisateur, aucun verrouillage
|
||
|
n'est effectué.
|
||
|
--lockdelay LOCKDELAY[=$LOCKDELAY]
|
||
|
Changer le nombre d'heures pendant lesquelles on autorise le script a
|
||
|
verrouiller l'exécution avant d'afficher un avertissement.
|
||
|
-n, --fake
|
||
|
Afficher au lieu de les exécuter les commandes qui doivent être lancées
|
||
|
-c, --continuous
|
||
|
Par défaut, ce script s'arrête à la première commande qui retourne avec
|
||
|
une code d'erreur. Avec cette option, ce script ne s'arrête jamais, bien
|
||
|
qu'il retourne toujours un code d'erreur si une erreur s'est produite.
|
||
|
-k, --stopec EXITCODE[=101]
|
||
|
Spécifier un code d'erreur spécial qui arrête ce script sans erreur, ou
|
||
|
'' pour désactiver cette fonctionnalité. Ceci permet en début de script
|
||
|
de faire des tests par exemple sur l'environnement avant de lancer les
|
||
|
scripts planifiés. Si l'environnement ne convient pas, il suffit au
|
||
|
script de contrôle de retourner le code d'erreur spécifique pour arrêter
|
||
|
le traitement."
|
||
|
}
|
||
|
|
||
|
MY_CTLINE="* * * * * $script"
|
||
|
LOCKDELAY=8
|
||
|
|
||
|
source "$(dirname "$0")/ulib/ulib" &&
|
||
|
urequire DEFAULTS crontab ||
|
||
|
exit 1
|
||
|
|
||
|
action=run
|
||
|
lockfile=auto
|
||
|
lockdelay=
|
||
|
fake=
|
||
|
continuous=
|
||
|
stopec=101
|
||
|
parse_opts "${PRETTYOPTS[@]}" \
|
||
|
--help '$exit_with display_help' \
|
||
|
--add,--install action=install \
|
||
|
--remove,--uninstall action=uninstall \
|
||
|
--lock: lockfile= \
|
||
|
--lockdelay: lockdelay= \
|
||
|
-n,--fake fake=1 \
|
||
|
-c,--continuous continuous=1 \
|
||
|
-k:,--stop: stopec=1 \
|
||
|
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
||
|
|
||
|
crontab="$1"; shift
|
||
|
[ -n "$crontab" ] || die_with "Vous devez spécifier le fichier crontab" display_help
|
||
|
[ -f "$crontab" ] || die "$crontab: fichier introuvable"
|
||
|
crontab="$(abspath "$crontab")"
|
||
|
|
||
|
if [ "$action" == "install" ]; then
|
||
|
enable_in_crontab "$MY_CTLINE $(quoted_arg "$crontab")" && estep "add_to_crontab $MY_CTLINE $(quoted_arg "$crontab")"
|
||
|
|
||
|
elif [ "$action" == "uninstall" ]; then
|
||
|
remove_from_crontab "$MY_CTLINE $(quoted_arg "$crontab")" && estep "remove_from_crontab $MY_CTLINE $(quoted_arg "$crontab")"
|
||
|
|
||
|
elif [ "$action" == "run" ]; then
|
||
|
if [ "$lockfile" == auto ]; then
|
||
|
if is_root; then
|
||
|
lockfile="/var/run/$scriptname$crontab.lock"
|
||
|
mkdirof "$lockfile" || die
|
||
|
else
|
||
|
lockfile=
|
||
|
fi
|
||
|
fi
|
||
|
[ -n "$lockdelay" ] || lockdelay="$LOCKDELAY"
|
||
|
|
||
|
if [ -n "$lockfile" ]; then
|
||
|
lockwarn="${lockfile%.lock}.lockwarn"
|
||
|
retry=1
|
||
|
while [ -n "$retry" ]; do
|
||
|
case "$(lf_trylock -h "$lockdelay" "$lockfile")" in
|
||
|
locked)
|
||
|
edebug "Arrêt du script parce que le verrou $lockfile est posé"
|
||
|
exit 0
|
||
|
;;
|
||
|
stale)
|
||
|
msg="Un verrou sur '$scriptname $crontab' est posé depuis plus de $lockdelay heures. Veuillez faire vos vérification et supprimer le cas échéant le fichier $lockfile"
|
||
|
logger -p cron.warn -t "$scriptname" -- "$msg"
|
||
|
if [ -f "$lockwarn" ]; then
|
||
|
edebug "$msg"
|
||
|
else
|
||
|
touch "$lockwarn"
|
||
|
ewarn "$msg"
|
||
|
fi
|
||
|
exit 1
|
||
|
;;
|
||
|
retry) :;;
|
||
|
*) retry=;;
|
||
|
esac
|
||
|
done
|
||
|
[ -f "$lockwarn" ] && rm "$lockwarn"
|
||
|
autoclean "$lockfile"
|
||
|
fi
|
||
|
|
||
|
function __ctexec() {
|
||
|
local ec=0
|
||
|
if [ -n "$fake" ]; then
|
||
|
echo "$*"
|
||
|
else
|
||
|
edebug "$*"
|
||
|
(eval "$*"); ec=$?
|
||
|
fi
|
||
|
[ -n "$stopec" -a "$ec" == "$stopec" ] && exit 0
|
||
|
[ -z "$continuous" -a "$ec" != 0 ] && exit "$ec"
|
||
|
return 0
|
||
|
}
|
||
|
function __cterror() {
|
||
|
die "$*"
|
||
|
}
|
||
|
ctscript="$(ctresolve <"$crontab")"
|
||
|
ec=0
|
||
|
edebug "$ctscript"
|
||
|
(eval "$ctscript"); ec=$?
|
||
|
[ -f "$lockfile" ] && rm "$lockfile"
|
||
|
exit "$ec"
|
||
|
fi
|