Merge branch 'uscrontab'
This commit is contained in:
commit
39d3c37912
|
@ -71,3 +71,13 @@ etitle "Installation de /etc/init.d/kvm-stop-all" \
|
|||
[ -n "$openvz_service" ] &&
|
||||
etitle "Installation de /etc/init.d/openvz-fix-etchosts" \
|
||||
"$scriptdir/../init.d/install-openvz-fix-etchosts"
|
||||
|
||||
etitle "Installation des répertoires pour uscrontab"
|
||||
if mkdir -p /var/uscrontab/crontabs; then
|
||||
chmod 1733 /var/uscrontab/crontabs
|
||||
else
|
||||
eerror "Impossible de créer le répertoire /var/uscrontab/crontabs"
|
||||
fi
|
||||
eend
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1 +1 @@
|
|||
34
|
||||
35
|
||||
|
|
18
ulib/base
18
ulib/base
|
@ -38,9 +38,9 @@ function recho() {
|
|||
if [[ "${1:0:2}" == -[eEn] ]]; then
|
||||
echo -n -
|
||||
local first="${1:1}"; shift
|
||||
echo "$first" "$@"
|
||||
echo "$first$@"
|
||||
else
|
||||
echo "$*"
|
||||
echo "$@"
|
||||
fi
|
||||
}
|
||||
function recho_() {
|
||||
|
@ -49,9 +49,9 @@ function recho_() {
|
|||
if [[ "${1:0:2}" == -[eEn] ]]; then
|
||||
echo -n -
|
||||
local first="${1:1}"; shift
|
||||
echo -n "$first" "$@"
|
||||
echo -n "$first$@"
|
||||
else
|
||||
echo -n "$*"
|
||||
echo -n "$@"
|
||||
fi
|
||||
}
|
||||
function qval() {
|
||||
|
@ -88,7 +88,7 @@ function qvals() {
|
|||
[ -z "$first" ] && echo -n " "
|
||||
if should_quote "$arg"; then
|
||||
echo -n \"
|
||||
qv "$arg"
|
||||
qval "$arg"
|
||||
echo -n \"
|
||||
else
|
||||
recho_ "$arg"
|
||||
|
@ -733,7 +733,7 @@ function array_extend_lasts() {
|
|||
function array_xsplit() {
|
||||
# créer le tableau $1 avec chaque élément de $2 (un ensemble d'éléments séparés
|
||||
# par $3, qui vaut ':' par défaut).
|
||||
eval "$1=($(<<<"$2" stripnl | awkrun RS="${3:-:}" '
|
||||
eval "$1=($(recho_ "$2" | awkrun RS="${3:-:}" '
|
||||
{
|
||||
gsub(/'\''/, "'\'\\\\\'\''")
|
||||
print "'\''" $0 "'\''"
|
||||
|
@ -743,7 +743,7 @@ function array_split() {
|
|||
# créer le tableau $1 avec chaque élément de $2 (un ensemble d'éléments séparés
|
||||
# par $3, qui vaut ':' par défaut). Les éléments vides sont ignorés. par exemple
|
||||
# "a::b" est équivalent à "a:b"
|
||||
eval "$1=($(<<<"$2" stripnl | awkrun RS="${3:-:}" '
|
||||
eval "$1=($(recho_ "$2" | awkrun RS="${3:-:}" '
|
||||
/^$/ { next }
|
||||
{
|
||||
gsub(/'\''/, "'\'\\\\\'\''")
|
||||
|
@ -755,7 +755,7 @@ function array_from_path() {
|
|||
}
|
||||
function array_from_xlines() {
|
||||
# créer le tableau $1 avec chaque ligne de $2.
|
||||
eval "$1=($(<<<"$2" _nl2lf | awk '
|
||||
eval "$1=($(recho_ "$2" | _nl2lf | awk '
|
||||
{
|
||||
gsub(/'\''/, "'\'\\\\\'\''")
|
||||
print "'\''" $0 "'\''"
|
||||
|
@ -763,7 +763,7 @@ function array_from_xlines() {
|
|||
}
|
||||
function array_from_lines() {
|
||||
# créer le tableau $1 avec chaque ligne de $2. Les lignes vides sont ignorés.
|
||||
eval "$1=($(<<<"$2" _nl2lf | awk '
|
||||
eval "$1=($(recho_ "$2" | _nl2lf | awk '
|
||||
/^$/ { next }
|
||||
{
|
||||
gsub(/'\''/, "'\'\\\\\'\''")
|
||||
|
|
180
uscrontab
180
uscrontab
|
@ -6,13 +6,22 @@ function display_help() {
|
|||
uecho "$scriptname: lancer une suite de commande en respectant une planification de type cron
|
||||
|
||||
USAGE
|
||||
$scriptname [options] /path/to/crontab
|
||||
$scriptname -l [/path/to/crontab]
|
||||
$scriptname [options] [/path/to/crontab]
|
||||
$scriptname -e [/path/to/crontab]
|
||||
$scriptname -l
|
||||
|
||||
La première forme du script doit normalement être lancé toutes les minutes par
|
||||
une tâche cron. Utiliser l'option --install pour ajouter automatique la ligne
|
||||
dans la crontab de l'utilisateur.
|
||||
|
||||
Si aucun fichier n'est spécifié, fusionner s'il existe le fichier
|
||||
$USCRONTAB_USERFILE
|
||||
avec chacun des fichiers du répertoire
|
||||
$USCRONTAB_USERDIR
|
||||
puis exécuter le fichier résultat avec le nom virtuel
|
||||
$USCRONTAB_USER
|
||||
note: le nom virtuel est utilisé pour le verrouillage avec --lock
|
||||
|
||||
A chaque lancement du script, il examine quels scripts doivent être exécutés
|
||||
dans le fichier crontab spécifié. Ce fichier est composé de lignes dans un
|
||||
format particulier, qui sont analysées et traitées dans l'ordre.
|
||||
|
@ -157,17 +166,29 @@ Les lignes commençant par # sont des commentaires et sont ignorées
|
|||
|
||||
OPTIONS
|
||||
-A, --install
|
||||
Installer une planification toutes les minutes de ce script dans la
|
||||
crontab de l'utilisateur. L'argument /path/to/crontab est requis.
|
||||
Installer une planification toutes les minutes du script dans la crontab
|
||||
de l'utilisateur. Si l'argument /path/to/crontab n'est pas spécifié,
|
||||
c'est une planification générique qui exécute les fichiers par défaut.
|
||||
-R, --uninstall
|
||||
Désinstaller la planification toutes les minutes de ce script du crontab
|
||||
de l'utilisateur. L'argument /path/to/crontab est requis, et seule cette
|
||||
instance est désinstallée le cas échéant.
|
||||
Désinstaller la planification toutes les minutes du script du crontab de
|
||||
l'utilisateur. Si l'argument /path/to/crontab est spécifié, cette
|
||||
instance est désinstallée. Sinon, ne désinstaller que la planification
|
||||
générique.
|
||||
-e, --edit
|
||||
Lancer un editeur pour modifier la crontab spécifiée. Si aucun fichier
|
||||
n'est spécifié, éditer $USCRONTAB_USERFILE
|
||||
-r, --remove
|
||||
Supprimer le fichier $USCRONTAB_USERFILE s'il existe
|
||||
Si l'argument /path/to/crontab est spécifié, il est ignoré.
|
||||
-l, --list
|
||||
Lister les contenus des fichiers crontab dont l'exécution a été
|
||||
planifiée avec --install
|
||||
Si /path/to/crontab est spécifié, ne lister le contenu de ce fichier que
|
||||
si son exécution a été planifiée.
|
||||
Si l'argument /path/to/crontab est spécifié, afficher le contenu de ce
|
||||
fichier. Sinon, lister les contenus des fichiers crontab qui sont
|
||||
exécutés avec la planification actuelle. Si une planification générique
|
||||
est installée, ou si aucune planification n'est en cours, afficher le
|
||||
contenu du fichier
|
||||
$USCRONTAB_USERFILE
|
||||
et chacun des fichiers du répertoire
|
||||
$USCRONTAB_USERDIR
|
||||
-n, --fake
|
||||
Afficher au lieu de les exécuter les commandes qui doivent être lancées
|
||||
|
||||
|
@ -198,9 +219,23 @@ OPTIONS AVANCEES
|
|||
le traitement."
|
||||
}
|
||||
|
||||
function set_usercrontabs() {
|
||||
# initialiser le tableau $1(=usercrontabs) avec la liste suivante: le
|
||||
# fichier $USCRONTAB_USERFILE s'il existe, puis la liste des fichiers dans
|
||||
# le répertoire $USCRONTAB_USERDIR
|
||||
local -a _userfile _userdir
|
||||
[ -f "$USCRONTAB_USERFILE" ] && _userfile=("$USCRONTAB_USERFILE")
|
||||
array_lsfiles _userdir "$USCRONTAB_USERDIR"
|
||||
eval "${1:-usercrontabs}"'=("${_userfile[@]}" "${_userdir[@]}")'
|
||||
}
|
||||
|
||||
USCRONTAB_CTLINE="* * * * * $script"
|
||||
USCRONTAB_LOCKDELAY=8
|
||||
USCRONTAB_STOPEC=101
|
||||
USCRONTAB_BASEDIR=/var/uscrontab
|
||||
USCRONTAB_USERFILE="$USCRONTAB_BASEDIR/crontabs/$USER"
|
||||
USCRONTAB_USERDIR="$USCRONTAB_BASEDIR/$USER.d"
|
||||
USCRONTAB_USER="$USCRONTAB_BASEDIR/$USER"
|
||||
|
||||
action=run
|
||||
lockfile=auto
|
||||
|
@ -217,43 +252,97 @@ parse_opts "${PRETTYOPTS[@]}" \
|
|||
-c,--continuous continuous=1 \
|
||||
-k:,--stop: USCRONTAB_STOPEC= \
|
||||
-l,--list action=list \
|
||||
-e,--edit action=edit \
|
||||
-r,--remove action=remove \
|
||||
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
||||
|
||||
if [ "$action" == "list" ]; then
|
||||
crontab="$1"; shift
|
||||
[ -n "$crontab" ] && crontab="$(abspath "$crontab")"
|
||||
crontab="$1"; shift
|
||||
|
||||
array_from_lines ctfiles "$(crontab -l 2>/dev/null | awkrun script="$script" '$6 == script { print $7 }')"
|
||||
found=
|
||||
for ctfile in "${ctfiles[@]}"; do
|
||||
if [ -z "$crontab" -o "$ctfile" == "$crontab" ]; then
|
||||
found=1
|
||||
etitle "$(ppath "$ctfile")"
|
||||
cat "$ctfile"
|
||||
eend
|
||||
if [ "$action" == "edit" ]; then
|
||||
if [ -z "$crontab" ]; then
|
||||
basedir="$(dirname "$USCRONTAB_USERFILE")"
|
||||
[ -d "$basedir" ] || die "$basedir: ce répertoire n'existe pas. Vérifiez l'installation de nutools"
|
||||
crontab="$USCRONTAB_USERFILE"
|
||||
fi
|
||||
done
|
||||
if [ -n "$crontab" -a -z "$found" ]; then
|
||||
ewarn "$(ppath "$crontab"): non planifié"
|
||||
enote "Edition de $crontab"
|
||||
if [ ! -f "$crontab" ]; then
|
||||
touch "$crontab"
|
||||
chmod 640 "$crontab"
|
||||
fi
|
||||
"${EDITOR:-vi}" "$crontab"
|
||||
exit 0
|
||||
|
||||
elif [ "$action" == "remove" ]; then
|
||||
[ -n "$crontab" ] && ewarn "$crontab: cet argument a été ignoré"
|
||||
crontab="$USCRONTAB_USERFILE"
|
||||
if [ -f "$crontab" ]; then
|
||||
ask_yesno "Voulez-vous supprimer le fichier $crontab?" C || die
|
||||
enote "Suppression de $crontab"
|
||||
rm "$crontab" || die
|
||||
fi
|
||||
exit 0
|
||||
|
||||
elif [ "$action" == "list" ]; then
|
||||
if [ -n "$crontab" ]; then
|
||||
crontab="$(abspath "$crontab")"
|
||||
array_from_lines ctfiles "$(crontab -l 2>/dev/null | awkrun script="$script" crontab="$crontab" '$6 == script && $7 == crontab { print $7 }')"
|
||||
if [ ${#ctfiles[*]} -eq 0 ]; then
|
||||
ewarn "$(ppath "$crontab"): non planifié"
|
||||
ctfiles=("$crontab")
|
||||
fi
|
||||
else
|
||||
array_from_lines ctfiles "$(crontab -l 2>/dev/null | awkrun script="$script" '$6 == script { if ($7) print $7; else print "GENERIC" }')"
|
||||
if array_contains ctfiles "GENERIC"; then
|
||||
# il y a une planification générique
|
||||
array_del ctfiles "GENERIC"
|
||||
set_usercrontabs usercrontabs
|
||||
array_extend ctfiles usercrontabs
|
||||
elif [ ${#ctfiles[*]} -eq 0 ]; then
|
||||
einfo "aucune planification en cours"
|
||||
set_usercrontabs ctfiles
|
||||
fi
|
||||
fi
|
||||
|
||||
r=1
|
||||
for ctfile in "${ctfiles[@]}"; do
|
||||
r=0 # il y a au moins une planification
|
||||
etitle "$(ppath "$ctfile")" \
|
||||
cat "$ctfile"
|
||||
done
|
||||
exit $r
|
||||
fi
|
||||
|
||||
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")"
|
||||
[ -z "$crontab" -o -f "$crontab" ] || die "$crontab: fichier introuvable"
|
||||
[ -n "$crontab" ] && crontab="$(abspath "$crontab")"
|
||||
|
||||
if [ "$action" == "install" ]; then
|
||||
enable_in_crontab "$USCRONTAB_CTLINE $(quoted_arg "$crontab")" && estep "add_to_crontab $USCRONTAB_CTLINE $(quoted_arg "$crontab")"
|
||||
ctline="$USCRONTAB_CTLINE"
|
||||
[ -n "$crontab" ] && ctline="$ctline $(quoted_arg "$crontab")"
|
||||
enable_in_crontab "$ctline" && estep "add_to_crontab $ctline"
|
||||
|
||||
elif [ "$action" == "uninstall" ]; then
|
||||
remove_from_crontab "$USCRONTAB_CTLINE $(quoted_arg "$crontab")" && estep "remove_from_crontab $USCRONTAB_CTLINE $(quoted_arg "$crontab")"
|
||||
ctline="$USCRONTAB_CTLINE"
|
||||
[ -n "$crontab" ] && ctline="$ctline $(quoted_arg "$crontab")"
|
||||
remove_from_crontab "$ctline" && estep "remove_from_crontab $ctline"
|
||||
|
||||
elif [ "$action" == "run" ]; then
|
||||
clean_crontab=
|
||||
if [ -n "$crontab" ]; then
|
||||
default_lockfile="/var/run/$scriptname$crontab.lock"
|
||||
else
|
||||
set_usercrontabs usercrontabs
|
||||
ac_set_tmpfile crontab
|
||||
clean_crontab=1
|
||||
for usercrontab in "${usercrontabs[@]}"; do
|
||||
echo "# $usercrontab" >>"$crontab"
|
||||
cat "$usercrontab" >>"$crontab"
|
||||
done
|
||||
default_lockfile="/var/run/$scriptname$USCRONTAB_USER.lock"
|
||||
fi
|
||||
|
||||
if [ "$lockfile" == auto ]; then
|
||||
if is_root; then
|
||||
lockfile="/var/run/$scriptname$crontab.lock"
|
||||
lockfile="$default_lockfile"
|
||||
mkdirof "$lockfile" || die
|
||||
else
|
||||
lockfile=
|
||||
|
@ -263,6 +352,8 @@ elif [ "$action" == "run" ]; then
|
|||
|
||||
if [ -n "$lockfile" ]; then
|
||||
lockwarn="${lockfile%.lock}.lockwarn"
|
||||
autoclean "$lockwarn"
|
||||
|
||||
retry=1
|
||||
while [ -n "$retry" ]; do
|
||||
case "$(lf_trylock -h "$lockdelay" "$lockfile")" in
|
||||
|
@ -285,7 +376,8 @@ elif [ "$action" == "run" ]; then
|
|||
*) retry=;;
|
||||
esac
|
||||
done
|
||||
[ -f "$lockwarn" ] && rm "$lockwarn"
|
||||
|
||||
ac_clean "$lockwarn"
|
||||
autoclean "$lockfile"
|
||||
fi
|
||||
|
||||
|
@ -314,21 +406,29 @@ elif [ "$action" == "run" ]; then
|
|||
ec=0
|
||||
edebug "$ctscript"
|
||||
(
|
||||
# tableau des fichiers de pid en cours. la conséquence est que ce n'est
|
||||
# pas une erreur d'appeler à plusieurs reprises check_pidfile avec le
|
||||
# même fichier
|
||||
__USCRONTAB_PIDFILES=()
|
||||
function check_pidfile() {
|
||||
if [ -n "$1" ]; then
|
||||
local pidfile="$(abspath "$1")"
|
||||
if ! array_contains __USCRONTAB_PIDFILES "$pidfile"; then
|
||||
local status
|
||||
pidfile_set -r "$1"; status=$?
|
||||
pidfile_set -r "$pidfile"; status=$?
|
||||
case "$status" in
|
||||
1)
|
||||
eerror "${2:-Une synchronisation} est en cours.
|
||||
Si vous pensez que c'est une erreur, veuillez vérifier le process de pid $(<"$1")
|
||||
puis supprimez le cas échéant le fichier $1"
|
||||
Si vous pensez que c'est une erreur, veuillez vérifier le process de pid $(<"$pidfile")
|
||||
puis supprimez le cas échéant le fichier $pidfile"
|
||||
return "$USCRONTAB_STOPEC"
|
||||
;;
|
||||
10)
|
||||
die "Une erreur s'est produite pendant l'écriture du fichier de pid. Impossible de continuer"
|
||||
;;
|
||||
esac
|
||||
array_add __USCRONTAB_PIDFILES "$pidfile"
|
||||
fi
|
||||
fi
|
||||
if [ -n "$3" -a -w "$(dirname "$3")" ]; then
|
||||
(set -o noclobber
|
||||
|
@ -340,12 +440,16 @@ puis supprimez le cas échéant le fichier $1"
|
|||
return 0
|
||||
}
|
||||
function remove_pidfile() {
|
||||
[ -n "$1" ] && ac_clean "$1"
|
||||
if [ -n "$1" ]; then
|
||||
local pidfile="$(abspath "$1")"
|
||||
ac_clean "$pidfile"
|
||||
array_del __USCRONTAB_PIDFILES "$pidfile"
|
||||
fi
|
||||
}
|
||||
__ac_forgetall
|
||||
eval "$ctscript"
|
||||
ac_cleanall
|
||||
); ec=$?
|
||||
[ -f "$lockfile" ] && rm "$lockfile"
|
||||
ac_clean "$lockfile"
|
||||
exit "$ec"
|
||||
fi
|
||||
|
|
Loading…
Reference in New Issue