Intégration de la branche release-7.2.0
This commit is contained in:
commit
4b30a7815b
25
CHANGES.md
25
CHANGES.md
|
@ -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
|
||||
|
||||
* `f131e21` uwatch: ajout de l'option -r
|
||||
|
|
|
@ -1 +1 @@
|
|||
7.1.0
|
||||
7.2.0
|
||||
|
|
13
authftp
13
authftp
|
@ -28,6 +28,9 @@ OPTIONS
|
|||
--tls
|
||||
Indiquer que la connexion se fera en TLS. Implique --lftp puisque ncftp
|
||||
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
|
||||
automatiquement avec lftp si le mot de passe contient une virgule. A cause de la
|
||||
|
@ -43,6 +46,7 @@ noproxy="$AUTHFTP_PROXY_DISABLED"
|
|||
lftp=
|
||||
options=()
|
||||
tls=
|
||||
verify_certificate=no
|
||||
parse_opts "${PRETTYOPTS[@]}" \
|
||||
--help '$exit_with display_help' \
|
||||
-p,--proxy noproxy= \
|
||||
|
@ -50,6 +54,7 @@ parse_opts "${PRETTYOPTS[@]}" \
|
|||
-l,--lftp lftp=1 \
|
||||
-o:,--option: options \
|
||||
--tls tls=1 \
|
||||
--verify-certificate verify_certificate=yes \
|
||||
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
||||
|
||||
[ -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 "$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
|
||||
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
|
||||
else
|
||||
if [ -n "$noproxy" ]; then
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
# -*- 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
|
||||
# pattern:destdir[:renamef]
|
||||
RULES=()
|
||||
|
|
|
@ -111,7 +111,15 @@ function copy_update_ask() {
|
|||
# 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
|
||||
# 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.
|
||||
local interopt=-c
|
||||
if [[ "$1" == -* ]]; then
|
||||
interopt="$1"
|
||||
shift
|
||||
fi
|
||||
local src="$1" dest="$2"
|
||||
|
||||
[ -d "$dest" ] && dest="$dest/$(basename -- "$src")"
|
||||
|
@ -119,10 +127,14 @@ function copy_update_ask() {
|
|||
|
||||
[ -f "$dest" ] || copy_replace "$src" "$dest"
|
||||
if testdiff "$src" "$dest"; then
|
||||
diff -u "$dest" "$src"
|
||||
if ask_yesno -c "Voulez-vous remplacer $(ppath "$dest") par la nouvelle version?" C; then
|
||||
check_interaction "$interopt" && diff -u "$dest" "$src"
|
||||
if ask_yesno "$interopt" "Voulez-vous remplacer $(ppath "$dest") par la nouvelle version?" C; then
|
||||
copy_replace "$src" "$dest" "$3"
|
||||
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
|
||||
return 1
|
||||
|
|
|
@ -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
50
ufile
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
# -*- 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
|
||||
urequire DEFAULTS
|
||||
urequire DEFAULTS multiconf
|
||||
|
||||
function display_help() {
|
||||
uecho "$scriptname: classer des fichiers selon certains règles
|
||||
|
@ -37,6 +37,7 @@ forme pattern:destdir[:renamef]
|
|||
|
||||
USAGE
|
||||
$scriptname [options] <files...>
|
||||
$scriptname [options] -r <files|dirs...>
|
||||
|
||||
OPTIONS
|
||||
-c, --config CONFIG
|
||||
|
@ -56,6 +57,9 @@ OPTIONS
|
|||
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
|
||||
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
|
||||
Afficher les opérations qui seraient faites
|
||||
-l, --list
|
||||
|
@ -116,6 +120,7 @@ args=(%
|
|||
--force-cp force_cp=1
|
||||
-S:,--ssh: SSH=
|
||||
--force-scp force_scp=1
|
||||
-r,--recursive recursive=1
|
||||
-n,--fake fake=1
|
||||
-l,--list action=list
|
||||
-e,--edit action=edit
|
||||
|
@ -126,8 +131,7 @@ parse_args "$@"; set -- "${args[@]}"
|
|||
|
||||
## charger toutes les règles
|
||||
|
||||
RULES=()
|
||||
INCLUDES=()
|
||||
conf_init -a RULES
|
||||
if [ -n "$config" ]; then
|
||||
if [ "$action" != edit ]; then
|
||||
# le fichier doit exister, sauf en mode édition où il sera créé s'il
|
||||
|
@ -140,22 +144,11 @@ if [ -n "$config" ]; then
|
|||
else
|
||||
set_defaults ufile
|
||||
fi
|
||||
array_copy rules RULES
|
||||
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
|
||||
conf_load "$HOME/etc/ufile.d/*.conf"
|
||||
|
||||
## actions particulières
|
||||
|
||||
if [ "$action" == list ]; then
|
||||
echo "# $(echo_seta2 INCLUDES)"
|
||||
array_to_lines RULES
|
||||
exit 0
|
||||
elif [ "$action" == edit ]; then
|
||||
|
@ -180,7 +173,7 @@ else
|
|||
fi
|
||||
|
||||
[ $# -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
|
||||
for rule in "${RULES[@]}"; do
|
||||
|
@ -194,13 +187,28 @@ for rule in "${RULES[@]}"; do
|
|||
fi
|
||||
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
|
||||
r=
|
||||
for file in "$@"; do
|
||||
[ -f "$file" -o -n "$fake" ] || {
|
||||
eerror "$file: fichier introuvable. il sera ignoré"
|
||||
continue
|
||||
}
|
||||
for file in "${files[@]}"; do
|
||||
setx pf=abspath "$file"
|
||||
setx dir=dirname -- "$pf"
|
||||
setx filename=basename -- "$pf"
|
||||
|
|
84
uscrontab
84
uscrontab
|
@ -234,6 +234,9 @@ OPTIONS
|
|||
$USCRONTAB_USERFILE
|
||||
et chacun des fichiers du répertoire
|
||||
$USCRONTAB_USERDIR
|
||||
-N, --nop
|
||||
Ne pas examiner la planification. Traiter uniquement l'option --osvar le
|
||||
cas échéant.
|
||||
-n, --fake
|
||||
Afficher au lieu de les exécuter les commandes qui doivent être lancées
|
||||
-P, --pause-for NBMINS
|
||||
|
@ -248,6 +251,9 @@ OPTIONS
|
|||
-f, --force
|
||||
Forcer l'exécution de la planification, même si elle a été mise en 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
|
||||
--lock LOCKFILE
|
||||
|
@ -286,6 +292,14 @@ OPTIONS AVANCEES
|
|||
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
|
||||
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
|
||||
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
|
||||
|
@ -345,8 +359,10 @@ lockfile=auto
|
|||
lockdelay=
|
||||
fake=
|
||||
continuous=
|
||||
force_ctnow=
|
||||
pause=
|
||||
force=
|
||||
osvars=()
|
||||
parse_opts "${PRETTYOPTS[@]}" \
|
||||
--help '$exit_with display_help' \
|
||||
-A,--add,--install action=install \
|
||||
|
@ -356,25 +372,50 @@ parse_opts "${PRETTYOPTS[@]}" \
|
|||
-a,--add action=add \
|
||||
-r,--remove action=remove \
|
||||
-l,--list action=list \
|
||||
-N,--nop action=nop \
|
||||
-n,--fake fake=1 \
|
||||
-P:,--pause-for: '$action=pause; set@ pause' \
|
||||
-p,--pause action=pause \
|
||||
-Y,--unpause action=unpause \
|
||||
-f,--force force=1 \
|
||||
-v:,--osvar: osvars \
|
||||
--lock: lockfile= \
|
||||
--lockdelay: lockdelay= \
|
||||
-c,--continuous continuous=1 \
|
||||
-k:,--stop: USCRONTAB_STOPEC= \
|
||||
--show-ctnow action=show-ctnow \
|
||||
--force-ctnow: __CTRESOLVE_CTNOW= \
|
||||
-@:,--hm: force_ctnow= \
|
||||
-H,--h00 force_ctnow=h00 \
|
||||
-M,--h30 force_ctnow=h30 \
|
||||
-G,--any-ctnow __CTRESOLVE_CTNOW="**ANY**" \
|
||||
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
||||
|
||||
uscrontab="$1"; shift
|
||||
|
||||
pausefile="$USCRONTAB_USERFILE.pauseuntil"
|
||||
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
|
||||
[ -n "$pause" ] || pause=1440
|
||||
if [ "$pause" -lt 0 ]; then
|
||||
|
@ -436,10 +477,6 @@ elif [ "$action" == "remove" ]; then
|
|||
exit 0
|
||||
|
||||
elif [ "$action" == "list" ]; then
|
||||
if check_pause "$pausefile" "$now"; then
|
||||
ewarn "En pause. Réactiver avec $scriptname -Y"
|
||||
fi
|
||||
|
||||
if [ -n "$uscrontab" ]; then
|
||||
uscrontab="$(abspath "$uscrontab")"
|
||||
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")" \
|
||||
cat "$ctfile"
|
||||
done
|
||||
|
||||
if check_pause "$pausefile" "$now"; then
|
||||
ewarn "En pause. Réactiver avec $scriptname -Y"
|
||||
fi
|
||||
exit $r
|
||||
|
||||
elif [ "$action" == "show-ctnow" ]; then
|
||||
ctnow "$now"
|
||||
exit 0
|
||||
|
||||
elif [ "$action" == "nop" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
[ -z "$uscrontab" -o -f "$uscrontab" ] || die "$uscrontab: fichier introuvable"
|
||||
|
@ -569,7 +613,7 @@ elif [ "$action" == "run" ]; then
|
|||
local cmd
|
||||
cmd="${1%% *}"
|
||||
case "$cmd" in
|
||||
check_pidfile|remove_pidfile|elogto) return 1;;
|
||||
check_pidfile|remove_pidfile|osvar|elogto) return 1;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
@ -604,6 +648,21 @@ elif [ "$action" == "run" ]; then
|
|||
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")"
|
||||
ec=0
|
||||
edebug "$__ctscript"
|
||||
|
@ -648,6 +707,17 @@ puis supprimez le cas échéant le fichier $pidfile"
|
|||
array_del __USCRONTAB_PIDFILES "$pidfile"
|
||||
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
|
||||
# Si des variables sont spécifiées, les initialiser avant de lancer le
|
||||
|
|
16
uwatch
16
uwatch
|
@ -18,6 +18,10 @@ OPTIONS
|
|||
Afficher un décompte depuis DURATION jusqu'à 0 puis terminer le script.
|
||||
DURATION exprimé en secondes est le premier argument du script et vaut
|
||||
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
|
||||
Avec l'option --count, afficher l'unité: sec., min. ou heures
|
||||
-o, --offset NBSEC
|
||||
|
@ -42,6 +46,8 @@ DEFAULT_STEP=1
|
|||
DEFAULT_DURATION=300
|
||||
|
||||
what=time
|
||||
wfile=
|
||||
wpid=
|
||||
units=
|
||||
offset=
|
||||
step=
|
||||
|
@ -52,6 +58,8 @@ args=(
|
|||
-t,--time what=time
|
||||
-c,--count what=count
|
||||
-r,--rcount what=rcount
|
||||
-f:,--wfile: wfile=
|
||||
-p:,--wpid: wpid=
|
||||
-u,--units units=1
|
||||
-o:,--offset: offset=
|
||||
-s:,--step: step=
|
||||
|
@ -112,5 +120,13 @@ while true; do
|
|||
msg="$msg (jusqu'à $until)"
|
||||
esac
|
||||
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"
|
||||
done
|
||||
|
|
Loading…
Reference in New Issue