Intégration de la branche release-7.2.0

This commit is contained in:
Jephté Clain 2017-09-26 17:01:37 +04:00
commit 4b30a7815b
9 changed files with 480 additions and 37 deletions

View File

@ -1,3 +1,28 @@
## Version 7.2.0 du 26/09/2017-17:01
* `1e576da` multiconf: rajouter conf_upgrade() dans conf_auto()
* `eeef48d` Intégration de la branche update-config
* `ea45055` implémentation simplifiée avec conf_upgrade()
* `efc60b3` description des modifications
* `36eec4a` Intégration de la branche update-ufile
* `2afffef` ne pas implémenter la recherche automatique de fichier de configuration
* `6ec37f6` ufile: implémenter l'option -r
* `6e8c200` maj TODO
* `cf629e6` uscrontab: support des oneshot vars
* `a66c0c2` uscrontab: ajout des options -@, -H, -M
* `52e838e` uwatch: ajouter les options -w et -p pour attendre la disparition d'un fichier ou d'un processus
* `8ad2e4c` lftp ne supporte pas l'utilisation des guillemets
* `7fb81a0` désactiver la vérification du certificat par défaut
* `dbc3daa` multiconf: bug
* `aff1c15` multiconf: support des variables de type path et compatibilité avec bash 4.3
* `8e17fb1` Intégration de la branche add-multiconf
* `a916180` ajouter conf_install pour installer les fichiers de configuration dans un répertoire standardisé
* `0372a5c` ufile charge les fichiers de ~/etc/ufile.d/
* `7d1ec90` simplifier l'API
* `c988692` fin implémentation
* `72e0c36` maj doc
* `f472501` squelette initial
## Version 7.1.0 du 10/09/2017-19:20 ## Version 7.1.0 du 10/09/2017-19:20
* `f131e21` uwatch: ajout de l'option -r * `f131e21` uwatch: ajout de l'option -r

View File

@ -1 +1 @@
7.1.0 7.2.0

13
authftp
View File

@ -28,6 +28,9 @@ OPTIONS
--tls --tls
Indiquer que la connexion se fera en TLS. Implique --lftp puisque ncftp Indiquer que la connexion se fera en TLS. Implique --lftp puisque ncftp
ne le supporte pas. ne le supporte pas.
--verify-certificate
Avec la connexion --tls, forcer la vérification du certificat, qui est
désactivée par défaut.
note: A cause d'une limitation de lftp, ce n'est pas possible de se connecter note: A cause d'une limitation de lftp, ce n'est pas possible de se connecter
automatiquement avec lftp si le mot de passe contient une virgule. A cause de la automatiquement avec lftp si le mot de passe contient une virgule. A cause de la
@ -43,6 +46,7 @@ noproxy="$AUTHFTP_PROXY_DISABLED"
lftp= lftp=
options=() options=()
tls= tls=
verify_certificate=no
parse_opts "${PRETTYOPTS[@]}" \ parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with display_help' \ --help '$exit_with display_help' \
-p,--proxy noproxy= \ -p,--proxy noproxy= \
@ -50,6 +54,7 @@ parse_opts "${PRETTYOPTS[@]}" \
-l,--lftp lftp=1 \ -l,--lftp lftp=1 \
-o:,--option: options \ -o:,--option: options \
--tls tls=1 \ --tls tls=1 \
--verify-certificate verify_certificate=yes \
@ args -- "$@" && set -- "${args[@]}" || die "$args" @ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -n "$noproxy" -o -n "$AUTHFTP_PROXY_HOST" ] || die "AUTHFTP_PROXY_HOST doit être défini" [ -n "$noproxy" -o -n "$AUTHFTP_PROXY_HOST" ] || die "AUTHFTP_PROXY_HOST doit être défini"
@ -66,9 +71,13 @@ read_value -i "Entrez le chemin" path "$4" N
if [ -n "$lftp" ]; then if [ -n "$lftp" ]; then
if [ -n "$noproxy" ]; then if [ -n "$noproxy" ]; then
exec lftp -u "$login,$password" "${options[@]}" "ftp://$host/$path" exec lftp "${options[@]}" -e "\
set ssl:verify-certificate $verify_certificate
open -u $login,$password ftp://$host/$path"
else else
exec lftp -u "${login}@${my_login}@${host},${password}@${my_password}" "${options[@]}" "ftp://$AUTHFTP_PROXY_HOST/$path" exec lftp "${options[@]}" -e "\
set ssl:verify-certificate $verify_certificate
open -u ${login}@${my_login}@${host},${password}@${my_password} ftp://$AUTHFTP_PROXY_HOST/$path"
fi fi
else else
if [ -n "$noproxy" ]; then if [ -n "$noproxy" ]; then

View File

@ -1,9 +1,5 @@
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
# Fichiers externes à inclure. Chacun de ces fichiers peut contenir des
# définitions de fonctions et de la variables RULES
INCLUDES=()
# Règles pour le classement des fichiers. Chaque règle est de la forme # Règles pour le classement des fichiers. Chaque règle est de la forme
# pattern:destdir[:renamef] # pattern:destdir[:renamef]
RULES=() RULES=()

View File

@ -111,7 +111,15 @@ function copy_update_ask() {
# Copier ou mettre à jour le fichier $1 vers le fichier $2. # Copier ou mettre à jour le fichier $1 vers le fichier $2.
# Si le fichier existe déjà, la différence est affichée, et une confirmation # Si le fichier existe déjà, la différence est affichée, et une confirmation
# est demandée pour l'écrasement du fichier. # est demandée pour l'écrasement du fichier.
# si $1 commence par '-' alors on s'en sert comme option pour configurer le
# niveau d'interaction pour demander la confirmation. les paramètres sont
# alors décalés
# Retourner vrai si le fichier a été copié sans erreur. # Retourner vrai si le fichier a été copié sans erreur.
local interopt=-c
if [[ "$1" == -* ]]; then
interopt="$1"
shift
fi
local src="$1" dest="$2" local src="$1" dest="$2"
[ -d "$dest" ] && dest="$dest/$(basename -- "$src")" [ -d "$dest" ] && dest="$dest/$(basename -- "$src")"
@ -119,10 +127,14 @@ function copy_update_ask() {
[ -f "$dest" ] || copy_replace "$src" "$dest" [ -f "$dest" ] || copy_replace "$src" "$dest"
if testdiff "$src" "$dest"; then if testdiff "$src" "$dest"; then
diff -u "$dest" "$src" check_interaction "$interopt" && diff -u "$dest" "$src"
if ask_yesno -c "Voulez-vous remplacer $(ppath "$dest") par la nouvelle version?" C; then if ask_yesno "$interopt" "Voulez-vous remplacer $(ppath "$dest") par la nouvelle version?" C; then
copy_replace "$src" "$dest" "$3" copy_replace "$src" "$dest" "$3"
return $? return $?
elif ! check_interaction "$interopt"; then
ewarn "Les mises à jours suivantes sont disponibles:"
diff -u "$dest" "$src"
ewarn "Le fichier $(ppath "$dest") n'a pas été mis à jour"
fi fi
fi fi
return 1 return 1

307
lib/ulib/multiconf Normal file
View File

@ -0,0 +1,307 @@
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Gestion de fichiers de configuration et de répertoires de configuration
##@cooked nocomments
uprovide multiconf
urequire install
function conf_local() {
# afficher les commandes pour définir comme locales les variables utilisées
# par les fonctions conf_*
# cela permet d'utiliser ces fonctions à l'intérieur d'autres fonctions sans
# polluer l'espace de nom
echo "local -a __CONF_DESCS __CONF_ARRAY_VARS __CONF_PATH_VARS"
}
function conf_auto() {
# charger la configuration pour l'outil $1 avec les variables $2..@
# conf_init n'est appelé que si des variables sont spécifiées, ce qui permet
# d'appeler conf_init au préalable si une configuration spécifique doit être
# faite.
# Ainsi:
# conf_auto NAME VARS...
# est équivalent à:
# conf_init VARS...
# conf_auto NAME
# est équivalent à:
# conf_init VARS...
# conf_find_files __CONF_FILES ~/etc/default/NAME.conf ~/etc/NAME.d/*.conf
# conf_upgrade ~/etc/default/NAME.conf
# conf_load_files "${__CONF_FILES[@]}"
# Pour supporter les scénarii où les fichiers de configuration sont ailleurs
# que dans ~/etc/default, l'argument NAME peut être un chemin:
# conf_auto PATH/TO/NAME VARS...
# est équivalent à:
# conf_init VARS...
# conf_find_files __CONF_FILES PATH/TO/NAME.conf PATH/TO/NAME.d/*.conf
# conf_upgrade PATH/TO/NAME.conf
# conf_load_files "${__CONF_FILES[@]}"
local __name="$1"; shift
[ -n "$__name" ] || return 1
[ $# -gt 0 ] && conf_init "$@"
local -a __CONF_FILES
if [[ "$__name" == */* ]]; then
conf_find_files __CONFS_FILES "$__name.conf" "$__name.d/*.conf"
[ $# -gt 0 ] && conf_upgrade "$__name.conf"
else
conf_find_files __CONFS_FILES "$HOME/etc/default/$__name.conf" "$HOME/etc/$__name.d/*.conf"
[ $# -gt 0 ] && conf_upgrade "$HOME/etc/default/$__name.conf"
fi
conf_load_files "${__CONFS_FILES[@]}"
}
function conf_init() {
# définir les variables attendues lors du chargement des fichiers de
# configuration par conf_load_files()
# Si cette fonction n'a pas d'argument, le contenu du tableau CONFIG s'il
# est existe est utilisé
# par défaut, les variables sont en mode scalaire: la définition d'une
# variable écrase la valeur précédente. Avec l'option -a les variables sont
# en mode tableau: les nouvelles valeurs sont rajoutées à la fin du tableau.
# Avec l'option -p les variables sont en mode chemin: les nouvelles valeurs
# sont ajoutées si elles n'existe pas déjà avec le séparateur ':'
# dans l'exemple suivant:
# conf_init NAME VALUE -a SRCDIRS DESTDIRS -p LIBPATH
# NAME et VALUE sont scalaires, SRCDIRS et DESTDIRS sont des tableaux et
# LIBPATH est de type chemin
# Les variables scalaires et chemin sont initialisées à la valeur vide ou à
# la valeur spécifiée e.g.:
# conf_init VAR=value MYPATH=a:b:c
# Les variables tableaux sont toujours initialisées à la valeur vide
# L'option -s permet de revenir au mode scalaire
# Note: il est possible d'associer une description à chaque variable ainsi
# qu'un en-tête, ce qui permet de construire le fichier de configuration ou
# de mettre à jour un fichier existant avec conf_upgrade(). Par exemple, les
# commandes suivantes:
# CONFIG=(
# "# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8"
# "# configurer l'application"
# -s
# "NAME=payet//nom de l'administrateur"
# "MAIL=admin@host.tld//mail de contact"
# -a
# "HOSTS//hôtes autorisés à se connecter"
# )
# conf_init
# permettent de générer automatiquement le fichier de configuration suivant:
# # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
# # configurer l'application
#
# # nom de l'administrateur
# #NAME=payet
#
# # mail de contact
# #MAIL=admin@host.tld
#
# # hôtes autorisés à se connecter
# #HOSTS=()
__CONF_DESCS=()
__CONF_ARRAY_VARS=()
__CONF_PATH_VARS=()
local __type=scalar __initial=1 __prefix __var __desc
[ $# -eq 0 ] && is_array CONFIG && set -- "${CONFIG[@]}"
while [ $# -gt 0 ]; do
if [ -n "$__initial" ]; then
if [ "${1:0:1}" == "#" ]; then
[ ${#__prefix} -gt 0 ] && __prefix="$__prefix"$'\n'
__prefix="$__prefix$1"
shift
continue
else
[ -n "$__prefix" ] && array_add __CONF_DESCS "$__prefix"
__initial=
fi
fi
case "$1" in
-a|--array) __type=array;;
-p|--path) __type=path;;
-s|--scalar) __type=scalar;;
*)
array_add __CONF_DESCS "$1"
splitfsep "$1" // __var __desc
case "$__type" in
array)
eval "${__var%%=*}=()"
array_addu __CONF_ARRAY_VARS "${__var%%=*}"
array_del __CONF_PATH_VARS "${__var%%=*}"
;;
path)
setv "$__var"
array_addu __CONF_PATH_VARS "${__var%%=*}"
array_del __CONF_ARRAY_VARS "${__var%%=*}"
;;
scalar)
setv "$__var"
;;
esac
;;
esac
shift
done
}
function conf_load() {
# charger les fichiers de configuration spécifiés
# conf_load SPECS...
# est équivalent à:
# conf_find_files __CONF_FILES SPECS...
# conf_load_files "${__CONF_FILES[@]}"
local -a __CONF_FILES
conf_find_files __CONFS_FILES "$@"
conf_load_files "${__CONFS_FILES[@]}"
}
function conf_find_files() {
# initialiser le tableau $1 avec les fichiers de configuration correspondant
# aux arguments $2..@
# - si on spécifie un fichier, il est pris tel quel s'il existe
# - si on spécifie un répertoire, tous les fichiers *.conf de ce répertoire
# sont pris
# - si on spécifie un pattern e.g path/to/*.conf alors tous les fichiers
# correspondant au pattern sont pris
# - sinon l'argument est ignoré
local __conf_dest="$1"; shift
local -a __conf_files
local __conf_spec __conf_dir __conf_wc
array_new "$__conf_dest"
for __conf_spec in "$@"; do
if [ -f "$__conf_spec" ]; then
array_add "$__conf_dest" "$__conf_spec"
continue
elif [ -d "$__conf_spec" ]; then
__conf_spec="$__conf_spec/*.conf"
fi
splitwcs "$__conf_spec" __conf_dir __conf_wc
array_lsfiles __conf_files "${__conf_dir:-.}" "$__conf_wc"
array_extend "$__conf_dest" __conf_files
done
}
function conf_load_files() {
# sourcer les fichiers spécifiés en faisant ce qui est nécessaire pour que
# les variables de __CONF_ARRAY_VARS soient correctement traitées.
local -a __conf_backups __conf_values
local __conf_file __conf_name __conf_i __conf_backup __conf_bn __conf_bv
for __conf_file in "$@"; do
# faire une copie de sauvegarde puis supprimer les variables tableaux
__conf_backups=()
for __conf_name in "${__CONF_ARRAY_VARS[@]}" "${__CONF_PATH_VARS[@]}"; do
__conf_backup="$(declare -p "$__conf_name" 2>/dev/null)"
if [ -z "$__conf_backup" ]; then
__conf_backup="$__conf_name="
else
# faire une correction de l'expression parce que la commande
# affichée par declare -p est différente entre bash 4.3 et bash
# 4.4 pour les tableaux. soit le tableau array=(a b)
# - bash 4.3 affiche declare -a array='([0]="a" [1]="b")'
# - bash 4.4 affiche declare -a array=([0]="a" [1]="b")
__conf_backup="${__conf_backup#declare }"
__conf_bn="${__conf_backup%% *}"
__conf_bv="${__conf_backup#* }"
if [[ "$__conf_bn" == -*a* ]]; then
__conf_bn="${__conf_bv%%=*}"
__conf_bv="${__conf_bv#*=}"
if [ "${__conf_bv:0:2}" == "'(" -a "${__conf_bv: -2:2}" == ")'" ]; then
__conf_backup="$__conf_bn=$(eval "echo $__conf_bv")"
else
__conf_backup="$__conf_bn=$__conf_bv"
fi
else
__conf_backup="$__conf_bv"
fi
fi
__conf_backups=("${__conf_backups[@]}" "$__conf_backup")
unset "$__conf_name"
done
# charger le fichier
source "$__conf_file"
# puis restaurer les variables ou les fusionner avec une éventuelle nouvelle valeur
__conf_i=0
for __conf_name in "${__CONF_ARRAY_VARS[@]}" "${__CONF_PATH_VARS[@]}"; do
__conf_backup="${__conf_backups[$__conf_i]}"
if [ -n "$(declare -p "$__conf_name" 2>/dev/null)" ]; then
# la variable a été redéfinie, la fusionner avec la précédente valeur
if array_contains __CONF_ARRAY_VARS "$__conf_name"; then
array_copy __conf_values "$__conf_name"
eval "$__conf_backup"
array_extend "$__conf_name" __conf_values
elif array_contains __CONF_PATH_VARS "$__conf_name"; then
__conf_values="${!__conf_name}"
eval "$__conf_backup"
uaddpath "$__conf_values" "$__conf_name"
fi
else
# la variable n'a pas été redéfinie, restaurer la précédente valeur
eval "$__conf_backup"
fi
__conf_i=$(($__conf_i + 1))
done
done
}
function conf_install() {
# USAGE: conf_install DEST SRCS...
# installer les fichiers de SRCS dans le répertoire standardisé DEST
# ## destination
# - si DEST est un nom sans chemin, e.g NAME, alors la destination est
# ~/etc/NAME.d
# - si DEST est un nom avec chemin, alors la valeur est prise telle quelle
# comme destination, et le répertoire est créé le cas échéant.
# Si un fichier existe déjà dans la destination, afficher une demande de
# confirmation avant de l'écraser
# ## source
# - si SRC est un fichier, le prendre tel quel
# - si SRC est un répertoire, prendre tous les fichiers SRC/*.conf
# - si SRC est un pattern, prendre tous les fichiers correspondant
local -a srcs
local src dir wc
local dest="$1"; shift
[[ "$dest" == */* ]] || dest="$HOME/etc/$dest.d"
mkdir -p "$dest" || return 1
for src in "$@"; do
if [ -f "$src" ]; then
srcs=("$src")
elif [ -d "$src" ]; then
array_lsfiles srcs "$src" "*.conf"
else
splitwcs "$src" dir wc
array_lsfiles srcs "$dir" "$wc"
fi
for src in "${srcs[@]}"; do
copy_update_ask -y "$src" "$dest"
done
done
}
function conf_upgrade() {
# USAGE: conf_upgrade DEST VARS...
# Si les variables VARS... sont spécifiées, on appelle au préalable conf_init()
local dest="$1"; shift
if [ $# -gt 0 ]; then
eval "$(conf_local)"
conf_init "$@"
fi
local desc namevalue name value
# calculer le préfixe et initialiser le fichier le cas échéant
if [ ! -f "$dest" ]; then
local prefix
for desc in "${__CONF_DESCS[@]}"; do
[ "${desc:0:1}" == "#" ] && prefix="$desc"
break
done
[ ${#prefix} -gt 0 ] || prefix="# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8"
echo "$prefix" >"$dest"
fi
# vérifier la présence de chaque variable
for desc in "${__CONF_DESCS[@]}"; do
[ "${desc:0:1}" == "#" ] && continue
splitfsep "$desc" // namevalue desc
splitvar "$namevalue" name value
if ! grep -qE "^\s*#*(\s*export)?\s*$name=" "$dest"; then
echo >>"$dest"
[ -n "$desc" ] && echo "# $desc" >>"$dest"
echo -n "#" >>"$dest"
echo_setv "$name" "$value" >>"$dest"
fi
done
}

50
ufile
View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib" || exit 1 source "$(dirname "$0")/lib/ulib/ulib" || exit 1
urequire DEFAULTS urequire DEFAULTS multiconf
function display_help() { function display_help() {
uecho "$scriptname: classer des fichiers selon certains règles uecho "$scriptname: classer des fichiers selon certains règles
@ -37,6 +37,7 @@ forme pattern:destdir[:renamef]
USAGE USAGE
$scriptname [options] <files...> $scriptname [options] <files...>
$scriptname [options] -r <files|dirs...>
OPTIONS OPTIONS
-c, --config CONFIG -c, --config CONFIG
@ -56,6 +57,9 @@ OPTIONS
Toujours utiliser scp pour une copie distante. Par défaut s'il est Toujours utiliser scp pour une copie distante. Par défaut s'il est
déterminé que l'hôte distant est en réalité l'hôte courant, alors la déterminé que l'hôte distant est en réalité l'hôte courant, alors la
copie est effectuée directement. copie est effectuée directement.
-r, --recursive
Classer récursivement tous les fichiers d'un répertoire. Sans cette
option, il n'est pas autorisé de fournir un répertoire comme argument.
-n, --fake -n, --fake
Afficher les opérations qui seraient faites Afficher les opérations qui seraient faites
-l, --list -l, --list
@ -116,6 +120,7 @@ args=(%
--force-cp force_cp=1 --force-cp force_cp=1
-S:,--ssh: SSH= -S:,--ssh: SSH=
--force-scp force_scp=1 --force-scp force_scp=1
-r,--recursive recursive=1
-n,--fake fake=1 -n,--fake fake=1
-l,--list action=list -l,--list action=list
-e,--edit action=edit -e,--edit action=edit
@ -126,8 +131,7 @@ parse_args "$@"; set -- "${args[@]}"
## charger toutes les règles ## charger toutes les règles
RULES=() conf_init -a RULES
INCLUDES=()
if [ -n "$config" ]; then if [ -n "$config" ]; then
if [ "$action" != edit ]; then if [ "$action" != edit ]; then
# le fichier doit exister, sauf en mode édition où il sera créé s'il # le fichier doit exister, sauf en mode édition où il sera créé s'il
@ -140,22 +144,11 @@ if [ -n "$config" ]; then
else else
set_defaults ufile set_defaults ufile
fi fi
array_copy rules RULES conf_load "$HOME/etc/ufile.d/*.conf"
for include in "${INCLUDES[@]}"; do
if [ -f "$include" ]; then
RULES=()
source "$include"
array_extend rules RULES
else
ewarn "$include: fichier introuvable"
fi
done
array_copy RULES rules
## actions particulières ## actions particulières
if [ "$action" == list ]; then if [ "$action" == list ]; then
echo "# $(echo_seta2 INCLUDES)"
array_to_lines RULES array_to_lines RULES
exit 0 exit 0
elif [ "$action" == edit ]; then elif [ "$action" == edit ]; then
@ -180,7 +173,7 @@ else
fi fi
[ $# -gt 0 ] || die "Vous devez spécifier des fichiers à classer" [ $# -gt 0 ] || die "Vous devez spécifier des fichiers à classer"
[ ${#RULES[*]} -gt 0 ] || die "Vous devez spécifier des règles pour le classement des fichiers dans ~/etc/default/ufile" [ ${#RULES[*]} -gt 0 ] || die "Vous devez spécifier des règles pour le classement des fichiers dans ~/etc/default/ufile ou ~/etc/ufile.d/*.conf"
# vérifier les règles # vérifier les règles
for rule in "${RULES[@]}"; do for rule in "${RULES[@]}"; do
@ -194,13 +187,28 @@ for rule in "${RULES[@]}"; do
fi fi
done done
# faire la liste des fichiers
files=()
for file in "$@"; do
if [ -d "$file" -a -n "$recursive" ]; then
setx file=abspath "$file"
array_from_lines rfiles "$(find "$file" -type f)"
array_extendu files rfiles
elif [ -f "$file" ]; then
setx file=abspath "$file"
array_addu files "$file"
elif [ -n "$fake" ]; then
: # on est en mode fake, pas grave si le fichier n'est pas trouvé
elif [ -d "$file" ]; then
eerror "$file: est un répertoire. essayez avec -r"
else
eerror "$file: fichier introuvable. il sera ignoré"
fi
done
# faire le classement effectif # faire le classement effectif
r= r=
for file in "$@"; do for file in "${files[@]}"; do
[ -f "$file" -o -n "$fake" ] || {
eerror "$file: fichier introuvable. il sera ignoré"
continue
}
setx pf=abspath "$file" setx pf=abspath "$file"
setx dir=dirname -- "$pf" setx dir=dirname -- "$pf"
setx filename=basename -- "$pf" setx filename=basename -- "$pf"

View File

@ -234,6 +234,9 @@ OPTIONS
$USCRONTAB_USERFILE $USCRONTAB_USERFILE
et chacun des fichiers du répertoire et chacun des fichiers du répertoire
$USCRONTAB_USERDIR $USCRONTAB_USERDIR
-N, --nop
Ne pas examiner la planification. Traiter uniquement l'option --osvar le
cas échéant.
-n, --fake -n, --fake
Afficher au lieu de les exécuter les commandes qui doivent être lancées Afficher au lieu de les exécuter les commandes qui doivent être lancées
-P, --pause-for NBMINS -P, --pause-for NBMINS
@ -248,6 +251,9 @@ OPTIONS
-f, --force -f, --force
Forcer l'exécution de la planification, même si elle a été mise en pause Forcer l'exécution de la planification, même si elle a été mise en pause
avec l'option --pause avec l'option --pause
-v, --osvar NAME[=VALUE]
Définir une variable de type oneshot. Par défaut, VALUE vaut 1 si elle
n'est pas spécifiée.
OPTIONS AVANCEES OPTIONS AVANCEES
--lock LOCKFILE --lock LOCKFILE
@ -286,6 +292,14 @@ OPTIONS AVANCEES
référence. Il faut respecter le format, sinon les résultats ne sont pas référence. Il faut respecter le format, sinon les résultats ne sont pas
garantis. Le mieux est de reprendre le résultat de l'option --show-ctnow garantis. Le mieux est de reprendre le résultat de l'option --show-ctnow
en le modifiant un peu si nécessaire. en le modifiant un peu si nécessaire.
-@, --hm H[:M]
-H, --h00
-M, --h30
Options pour simplifier l'utilisation de --force-ctnow. Supposons que
--show-ctnow affiche 'Y X day mon dow', alors:
-@ H:M | est équivalent à | --force-ctnow 'M H day mon dow'
-H | '' | --force-ctnow '0 X day mon dow'
-M | '' | --force-ctnow '30 X day mon dow'
-G, --any-ctnow -G, --any-ctnow
Pour le développement ou des tests, lancer toutes les commandes dans Pour le développement ou des tests, lancer toutes les commandes dans
l'ordre sans tenir compte de l'heure de référence. Cette commande ne l'ordre sans tenir compte de l'heure de référence. Cette commande ne
@ -345,8 +359,10 @@ lockfile=auto
lockdelay= lockdelay=
fake= fake=
continuous= continuous=
force_ctnow=
pause= pause=
force= force=
osvars=()
parse_opts "${PRETTYOPTS[@]}" \ parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with display_help' \ --help '$exit_with display_help' \
-A,--add,--install action=install \ -A,--add,--install action=install \
@ -356,25 +372,50 @@ parse_opts "${PRETTYOPTS[@]}" \
-a,--add action=add \ -a,--add action=add \
-r,--remove action=remove \ -r,--remove action=remove \
-l,--list action=list \ -l,--list action=list \
-N,--nop action=nop \
-n,--fake fake=1 \ -n,--fake fake=1 \
-P:,--pause-for: '$action=pause; set@ pause' \ -P:,--pause-for: '$action=pause; set@ pause' \
-p,--pause action=pause \ -p,--pause action=pause \
-Y,--unpause action=unpause \ -Y,--unpause action=unpause \
-f,--force force=1 \ -f,--force force=1 \
-v:,--osvar: osvars \
--lock: lockfile= \ --lock: lockfile= \
--lockdelay: lockdelay= \ --lockdelay: lockdelay= \
-c,--continuous continuous=1 \ -c,--continuous continuous=1 \
-k:,--stop: USCRONTAB_STOPEC= \ -k:,--stop: USCRONTAB_STOPEC= \
--show-ctnow action=show-ctnow \ --show-ctnow action=show-ctnow \
--force-ctnow: __CTRESOLVE_CTNOW= \ --force-ctnow: __CTRESOLVE_CTNOW= \
-@:,--hm: force_ctnow= \
-H,--h00 force_ctnow=h00 \
-M,--h30 force_ctnow=h30 \
-G,--any-ctnow __CTRESOLVE_CTNOW="**ANY**" \ -G,--any-ctnow __CTRESOLVE_CTNOW="**ANY**" \
@ args -- "$@" && set -- "${args[@]}" || die "$args" @ args -- "$@" && set -- "${args[@]}" || die "$args"
uscrontab="$1"; shift
pausefile="$USCRONTAB_USERFILE.pauseuntil" pausefile="$USCRONTAB_USERFILE.pauseuntil"
now="$(awk 'BEGIN { print int(systime() / 60) * 60 }')" now="$(awk 'BEGIN { print int(systime() / 60) * 60 }')"
# ne prendre le premier argument comme un fichier que s'il existe ou s'il n'est
# pas de la forme *=*
if [[ "$1" == *=* ]]; then
if [ -f "$1" ]; then
uscrontab="$1"; shift
fi
else
uscrontab="$1"; shift
fi
# écrire les variables oneshot
for osvar in "${osvars[@]}"; do
if [[ "$osvar" == *=* ]]; then
splitvar "$osvar" name value
else
name="$osvar"
value=1
fi
name="${name##*/}" # au cas où...
echo -n "$value" >"$USCRONTAB_USERFILE.$name.osvar"
done
if [ "$action" == "pause" ]; then if [ "$action" == "pause" ]; then
[ -n "$pause" ] || pause=1440 [ -n "$pause" ] || pause=1440
if [ "$pause" -lt 0 ]; then if [ "$pause" -lt 0 ]; then
@ -436,10 +477,6 @@ elif [ "$action" == "remove" ]; then
exit 0 exit 0
elif [ "$action" == "list" ]; then elif [ "$action" == "list" ]; then
if check_pause "$pausefile" "$now"; then
ewarn "En pause. Réactiver avec $scriptname -Y"
fi
if [ -n "$uscrontab" ]; then if [ -n "$uscrontab" ]; then
uscrontab="$(abspath "$uscrontab")" uscrontab="$(abspath "$uscrontab")"
array_from_lines ctfiles "$(crontab -l 2>/dev/null | awkrun script="$script" uscrontab="$uscrontab" '$6 == script && $7 == uscrontab { print $7 }')" array_from_lines ctfiles "$(crontab -l 2>/dev/null | awkrun script="$script" uscrontab="$uscrontab" '$6 == script && $7 == uscrontab { print $7 }')"
@ -472,11 +509,18 @@ elif [ "$action" == "list" ]; then
etitle "$(ppath "$ctfile")" \ etitle "$(ppath "$ctfile")" \
cat "$ctfile" cat "$ctfile"
done done
if check_pause "$pausefile" "$now"; then
ewarn "En pause. Réactiver avec $scriptname -Y"
fi
exit $r exit $r
elif [ "$action" == "show-ctnow" ]; then elif [ "$action" == "show-ctnow" ]; then
ctnow "$now" ctnow "$now"
exit 0 exit 0
elif [ "$action" == "nop" ]; then
exit 0
fi fi
[ -z "$uscrontab" -o -f "$uscrontab" ] || die "$uscrontab: fichier introuvable" [ -z "$uscrontab" -o -f "$uscrontab" ] || die "$uscrontab: fichier introuvable"
@ -569,7 +613,7 @@ elif [ "$action" == "run" ]; then
local cmd local cmd
cmd="${1%% *}" cmd="${1%% *}"
case "$cmd" in case "$cmd" in
check_pidfile|remove_pidfile|elogto) return 1;; check_pidfile|remove_pidfile|osvar|elogto) return 1;;
esac esac
return 0 return 0
} }
@ -604,6 +648,21 @@ elif [ "$action" == "run" ]; then
die "$*" die "$*"
} }
if [ -n "$force_ctnow" ]; then
ctnow=($(ctnow "$now"))
case "$force_ctnow" in
h00) ctnow[0]=0;;
h30) ctnow[0]=30;;
*)
force_ctnow="${force_ctnow//./:}" # autoriser H.M en plus de H:M
splitpair "$force_ctnow" h m
ctnow[0]="${m:-0}"
ctnow[1]="$h"
;;
esac
__CTRESOLVE_CTNOW="${ctnow[*]}"
fi
__ctscript="$(ctresolve <"$uscrontab")" __ctscript="$(ctresolve <"$uscrontab")"
ec=0 ec=0
edebug "$__ctscript" edebug "$__ctscript"
@ -648,6 +707,17 @@ puis supprimez le cas échéant le fichier $pidfile"
array_del __USCRONTAB_PIDFILES "$pidfile" array_del __USCRONTAB_PIDFILES "$pidfile"
fi fi
} }
function osvar() {
local __name __value
for __name in "$@"; do
splitvar "$__name" __name __value
if [ -f "$USCRONTAB_USERFILE.$__name.osvar" ]; then
__value="$(<"$USCRONTAB_USERFILE.$__name.osvar")"
rm "$USCRONTAB_USERFILE.$__name.osvar"
fi
_setv "$__name" "$__value"
done
}
__ac_forgetall __ac_forgetall
# Si des variables sont spécifiées, les initialiser avant de lancer le # Si des variables sont spécifiées, les initialiser avant de lancer le

16
uwatch
View File

@ -18,6 +18,10 @@ OPTIONS
Afficher un décompte depuis DURATION jusqu'à 0 puis terminer le script. Afficher un décompte depuis DURATION jusqu'à 0 puis terminer le script.
DURATION exprimé en secondes est le premier argument du script et vaut DURATION exprimé en secondes est le premier argument du script et vaut
par défaut ${DEFAULT_DURATION} soit $(($DEFAULT_DURATION / 60)) minutes. par défaut ${DEFAULT_DURATION} soit $(($DEFAULT_DURATION / 60)) minutes.
-f, --wfile FILE
Arrêter dès que le fichier FILE n'existe plus
-p, --wpid PID
Arrêter dès que la processus PID n'existe plus
-u, --units -u, --units
Avec l'option --count, afficher l'unité: sec., min. ou heures Avec l'option --count, afficher l'unité: sec., min. ou heures
-o, --offset NBSEC -o, --offset NBSEC
@ -42,6 +46,8 @@ DEFAULT_STEP=1
DEFAULT_DURATION=300 DEFAULT_DURATION=300
what=time what=time
wfile=
wpid=
units= units=
offset= offset=
step= step=
@ -52,6 +58,8 @@ args=(
-t,--time what=time -t,--time what=time
-c,--count what=count -c,--count what=count
-r,--rcount what=rcount -r,--rcount what=rcount
-f:,--wfile: wfile=
-p:,--wpid: wpid=
-u,--units units=1 -u,--units units=1
-o:,--offset: offset= -o:,--offset: offset=
-s:,--step: step= -s:,--step: step=
@ -112,5 +120,13 @@ while true; do
msg="$msg (jusqu'à $until)" msg="$msg (jusqu'à $until)"
esac esac
echo -n $'\e[1G\e[K'"$prefix$msg$suffix" echo -n $'\e[1G\e[K'"$prefix$msg$suffix"
if [ -n "$wfile" -a ! -f "$wfile" ]; then
echo
break
fi
if [ -n "$wpid" ] && ! kill -0 "$wpid" 2>/dev/null; then
echo
break
fi
sleep "$step" sleep "$step"
done done