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 | ||||||
|  | |||||||
							
								
								
									
										307
									
								
								lib/ulib/multiconf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										307
									
								
								lib/ulib/multiconf
									
									
									
									
									
										Normal 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
									
									
									
									
									
								
							
							
						
						
									
										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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user