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
|
## Version 7.1.0 du 10/09/2017-19:20
|
||||||
|
|
||||||
* `f131e21` uwatch: ajout de l'option -r
|
* `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
|
--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
|
||||||
|
|
|
@ -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=()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
#!/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"
|
||||||
|
|
84
uscrontab
84
uscrontab
|
@ -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
16
uwatch
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue