2013-08-27 15:14:44 +04:00
|
|
|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
|
|
|
|
|
|
|
##################################################
|
|
|
|
# Gestion des fichiers
|
|
|
|
|
|
|
|
function filter_conf() {
|
|
|
|
# filtrer un fichier de configuration en enlevant les commentaires et les lignes vides
|
|
|
|
# $1==-m fusionner les lignes qui se terminent par \
|
|
|
|
local merge=cat
|
|
|
|
if [ "$1" == -m ]; then
|
|
|
|
merge='awk '\''substr($0, length($0)) == "\\" { while (substr($0, length($0)) == "\\") { getline nextline; $0 = substr($0, 1, length($0) - 1) nextline }; print; next } {print}'\'
|
|
|
|
fi
|
|
|
|
grep -v '^#' | grep -v '^$' | eval "$merge"
|
|
|
|
}
|
|
|
|
|
|
|
|
##################################################
|
|
|
|
# Gestion des fichiers et répertoires temporaires
|
|
|
|
function make_tempfile() {
|
|
|
|
# $1=template du fichier à créer
|
|
|
|
local mktmpdir=
|
|
|
|
if [ "$1" == "-d" ]; then
|
|
|
|
shift
|
|
|
|
mktmpdir=1
|
|
|
|
fi
|
|
|
|
local template="${1:-$TMPDIR/tmp.XXXXXX}"
|
|
|
|
local base="${template%%X*}"
|
|
|
|
local XXXs="${template#$base}"
|
|
|
|
[ -z "$XXXs" ] && XXXs="XXXXXX"
|
|
|
|
local nbX="${#XXXs}"
|
|
|
|
|
|
|
|
local n="$$0" suff
|
|
|
|
while true; do
|
|
|
|
suff="$n"
|
|
|
|
while [ ${#suff} -lt $nbX ]; do suff="0$suff"; done
|
|
|
|
|
|
|
|
tempfile="$base$suff"
|
|
|
|
if [ -n "$mktmpdir" ]; then
|
|
|
|
# répertoire temporaire
|
|
|
|
if [ ! -d "$tempfile" ]; then
|
|
|
|
mkdir "$tempfile"
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
# fichier temporaire
|
|
|
|
if [ ! -f "$tempfile" ]; then
|
|
|
|
touch "$tempfile"
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
n=$(($n + 1))
|
|
|
|
done
|
|
|
|
|
|
|
|
echo "$tempfile"
|
|
|
|
}
|
|
|
|
|
|
|
|
# autoclean: gérer une liste de fichiers temporaires à supprimer en fin de programme
|
|
|
|
__ac_files=()
|
|
|
|
function __ac_trap() {
|
|
|
|
local file_
|
|
|
|
for file_ in "${__ac_files[@]}"; do
|
|
|
|
[ -e "$file_" ] && rm -rf "$file_"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
trap __ac_trap 1 3 15 EXIT
|
|
|
|
function autoclean() {
|
|
|
|
# Ajouter $1..$n à la liste des fichiers à supprimer à la fin du programme
|
|
|
|
local file_
|
|
|
|
for file_ in "$@"; do
|
|
|
|
[ -n "$file_" ] && array_add __ac_files "$file_"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
function ac_set_tmpfile() {
|
|
|
|
# Créer un fichier temporaire avec le motif $2, l'ajouter à la liste des
|
|
|
|
# fichiers à supprimer en fin de programme, et mettre sa valeur dans la
|
|
|
|
# variable $1
|
|
|
|
local tmpfile_="$(mktempf "$2")"
|
|
|
|
autoclean "$tmpfile_"
|
|
|
|
set_var "$1" "$tmpfile_"
|
|
|
|
}
|
|
|
|
function ac_set_tmpdir() {
|
|
|
|
# Créer un répertoire temporaire avec le motif $2, l'ajouter à la liste des
|
|
|
|
# fichiers à supprimer en fin de programme, et mettre sa valeur dans la
|
|
|
|
# variable $1
|
|
|
|
local tmpdir_="$(mktempd "$2")"
|
|
|
|
autoclean "$tmpdir_"
|
|
|
|
set_var "$1" "$tmpdir_"
|
|
|
|
}
|
|
|
|
|
|
|
|
##################################################
|
|
|
|
# args: gestion d'un ensemble d'arguments
|
|
|
|
|
|
|
|
function read_args() {
|
|
|
|
# Lire les arguments et les mettre sur plusieurs lignes dans la variable
|
|
|
|
# dont le nom est donné dans $1. Ceci permet de façon fiable de traiter des
|
|
|
|
# arguments avec des espaces dedans.
|
|
|
|
|
|
|
|
# note: cela suppose bien sûr que les arguments ne contiennent pas de retour
|
|
|
|
# à la ligne!!!
|
|
|
|
if [ -z "$1" ]; then return 1; fi
|
|
|
|
|
|
|
|
local varname_="$1"; shift
|
|
|
|
local args_ arg_
|
|
|
|
|
|
|
|
for arg_ in "$@"; do
|
|
|
|
args_="${args_:+$args_
|
|
|
|
}$arg_"
|
|
|
|
done
|
|
|
|
set_var "$varname_" "$args_"
|
|
|
|
}
|
|
|
|
|
|
|
|
function next_arg() {
|
|
|
|
# Soit la variable args dont le nom est donné dans $1, et la variable next
|
|
|
|
# dont le nom est donné dans $2. Mettre à jour next avec la première ligne
|
|
|
|
# de la variable args. Mettre à jour args avec le reste des lignes.
|
|
|
|
if [ -z "$1" -o -z "$2" ]; then return 1; fi
|
|
|
|
|
|
|
|
local args_="$1"
|
|
|
|
local arg_="$2"
|
|
|
|
local line_ first_=1 first_line_ last_lines_
|
|
|
|
|
|
|
|
eval "$((echo "${!args_}"; echo "---<eof>---") | while read line_; do
|
|
|
|
if [ "$line_" == "---<eof>---" ]; then
|
|
|
|
echo "first_line_=\"$(quote_arg "$first_line_")\"
|
|
|
|
last_lines_=\"$(echo "$last_lines_" | awk '/.+/ { print; next }' | quote_string)\""
|
|
|
|
elif [ -n "$first_" ]; then
|
|
|
|
first_=
|
|
|
|
first_line_="$line_"
|
|
|
|
else
|
|
|
|
last_lines_="$last_lines_
|
|
|
|
$line_"
|
|
|
|
fi
|
|
|
|
done)"
|
|
|
|
set_var "$args_" "$last_lines_"
|
|
|
|
set_var "$arg_" "$first_line_"
|
|
|
|
if [ -z "$first_line_" ]; then return 1; fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_option() {
|
|
|
|
# $1 est un argument de la forme "option:value"
|
|
|
|
# $2 est une liste d'options valides, séparées par des espaces
|
|
|
|
# $3 est un suffixe à rajouter au nom de variable
|
|
|
|
|
|
|
|
# Si $1 est une option valide (de la forme 'option:value' avec option
|
|
|
|
# faisant partie de la liste (optionnelle) des options valides) alors mettre
|
|
|
|
# à jour la variable $option avec la valeur value. sinon, retourner un code
|
|
|
|
# d'erreur
|
|
|
|
|
|
|
|
local arg_="$1"
|
|
|
|
local valid_options_="$2" valid_option_ is_valid_ option_ value_
|
|
|
|
local suffix_="$3"
|
|
|
|
|
|
|
|
option_="$(expr "$arg_" : "\(..*\):")"
|
|
|
|
[ -z "$option_" ] && return 1
|
|
|
|
|
|
|
|
if [ -n "$2" ]; then
|
|
|
|
# vérifier que $option est valide
|
|
|
|
is_valid_=
|
|
|
|
for valid_option_ in $valid_options_; do
|
|
|
|
if [ "$option_" == "$valid_option_" ]; then
|
|
|
|
is_valid_=1
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
[ -z "$is_valid_" ] && return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
value_="${1##$option_:}"
|
|
|
|
set_var "$option_$suffix_" "$value_"
|
|
|
|
}
|
|
|
|
|
|
|
|
##################################################
|
|
|
|
# input: fonctions pour poser des question et saisir des valeurs
|
|
|
|
|
|
|
|
function ask_yesno() {
|
|
|
|
# $1=message, $2=default (N par défaut)
|
|
|
|
# Afficher le message $message suivi de [oN] ou [On] suivant que $default
|
|
|
|
# vaut O ou N. Retourner 0 si la réponse est oui, 1 sinon
|
|
|
|
|
|
|
|
# Si default vaut C, alors la valeur par défaut dépend du niveau
|
|
|
|
# d'interactivité: N si on est interactif et O si on est pas interactif
|
|
|
|
|
|
|
|
# Support de l'affichage de la question suivant le niveau d'interaction
|
|
|
|
# et/ou de verbosité Le message ne sera affiché que si le niveau
|
|
|
|
# d'interaction (ou de verbosité) courant est supérieur ou égal à celui qui
|
|
|
|
# est spécifié en argument. Sinon, la valeur par défaut est retournée
|
|
|
|
local r
|
|
|
|
check_verbosity "$1"; r=$?; [ $r -le 1 ] && shift
|
|
|
|
|
|
|
|
local message="$1"
|
|
|
|
local prompt="[oN]"
|
|
|
|
local default="${2:-N}"
|
|
|
|
if [ "$default" == "C" ]; then
|
|
|
|
if [ $r -ne 1 ]; then
|
|
|
|
default=N
|
|
|
|
else
|
|
|
|
default=O
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
is_yes "$default" && prompt="[On]"
|
|
|
|
|
|
|
|
if [ $r -ne 1 ]; then
|
|
|
|
if [ -n "$message" ]; then
|
|
|
|
tooenc_ "$message"
|
|
|
|
else
|
|
|
|
tooenc_ "Voulez-vous continuer?" "$UTF8"
|
|
|
|
fi
|
|
|
|
echo_ " $prompt "
|
|
|
|
uread r
|
|
|
|
else
|
|
|
|
r=
|
|
|
|
fi
|
|
|
|
|
|
|
|
is_yes "${r:-$default}"
|
|
|
|
}
|
|
|
|
|
|
|
|
function read_value() {
|
|
|
|
# $1=message, $2=varname, $3=default, $4=refuse_empty
|
|
|
|
# Afficher le message $message suivi la valeur par défaut [$default] si elle
|
|
|
|
# est non vide, puis lire la valeur donnée par l'utilisateur. Cette valeur
|
|
|
|
# doit être non vide si $refuse_empty est vrai (ce qui est le cas par
|
|
|
|
# défaut)
|
|
|
|
# La valeur saisie est placée dans la variable $varname (par défaut value)
|
|
|
|
|
|
|
|
# note: les variables locales sont suffixées de _ pour éviter que $varname
|
|
|
|
# soit égal à une des variables locales.
|
|
|
|
|
|
|
|
# Support l'affichage de la question suivant le niveau de "verbosité"
|
|
|
|
# Le message ne sera affiché que si le niveau de verbosité courant est
|
|
|
|
# supérieur ou égal à celui qui est spécifié en argument. Sinon, la valeur
|
|
|
|
# par défaut est retournée. (note: si l'utilisateur requière que la valeur
|
|
|
|
# soit non vide et que la valeur par défaut est vide, le script s'arrête
|
|
|
|
# avec une erreur)
|
|
|
|
local r_
|
|
|
|
check_verbosity "$1"; r_=$?; [ $r_ -le 1 ] && shift
|
|
|
|
|
|
|
|
local message_="$1"
|
|
|
|
local varname_="${2:-value}"
|
|
|
|
local default_="$3"
|
|
|
|
local refuse_empty_="${4:-O}"
|
|
|
|
|
|
|
|
local read_value_=
|
|
|
|
if [ $r_ -ne 1 ]; then
|
|
|
|
read_value_=1
|
|
|
|
elif [ -z "$default_" ] && is_yes "$refuse_empty_"; then
|
|
|
|
read_value_=1
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -n "$read_value_" ]; then
|
|
|
|
while true; do
|
|
|
|
if [ -n "$message_" ]; then
|
|
|
|
tooenc_ "$message_"
|
|
|
|
else
|
|
|
|
tooenc_ "Entrez la valeur" "$UTF8"
|
|
|
|
fi
|
|
|
|
[ -n "$default_" ] && tooenc_ " [$default_]"
|
|
|
|
echo_ ": "
|
|
|
|
uread r_; r_="${r_:-$default_}"
|
|
|
|
if [ -n "$r_" ] || ! is_yes "$refuse_empty_"; then
|
|
|
|
set_var "$varname_" "$r_"
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
else
|
|
|
|
if [ -z "$default_" ] && is_yes "$refuse_empty_"; then
|
|
|
|
OENC="$UTF8" die "La valeur par défaut de $varname_ doit être non vide"
|
|
|
|
else
|
|
|
|
set_var "$varname_" "$default_"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
##################################################
|
|
|
|
# menu: fonctions afficher un menu
|
|
|
|
|
|
|
|
function simple_menu() {
|
|
|
|
# $1=option_varname
|
|
|
|
# $2=options (une par ligne)
|
|
|
|
# $3..*=votre_choix:, titre_du_menu:, choix_par_defaut:
|
|
|
|
|
|
|
|
# Afficher un menu dont les membres sont les lignes de $options. Un choix
|
|
|
|
# doit être saisi sous la forme num_option. L'option choisie est placée dans
|
|
|
|
# la variable $option_varname
|
|
|
|
|
|
|
|
# note: les variables locales sont suffixées de _ pour éviter que
|
|
|
|
# $option_varname soit égal à une des variables locales.
|
|
|
|
|
|
|
|
local tab_=" " # contient une tabulation
|
|
|
|
local i_ c_
|
|
|
|
local options_one_by_line_ options_ option_
|
|
|
|
local choice_ choice_option_
|
|
|
|
local option_varname_
|
|
|
|
local votre_choix_ titre_du_menu_ choix_par_defaut_
|
|
|
|
|
|
|
|
# nom de la variable destination
|
|
|
|
option_varname_="$1"; shift
|
|
|
|
if [ -z "$option_varname_" ]; then
|
|
|
|
OENC="$UTF8" eerror "option_varname doit être spécifié"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
choix_par_defaut_="${!option_varname_}"
|
|
|
|
|
|
|
|
# Construire le tableau des options
|
|
|
|
options_one_by_line_="$1"; shift
|
|
|
|
if [ -z "$options_one_by_line_" ]; then
|
|
|
|
OENC="$UTF8" eerror "options doit être non vide"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
i_=0
|
|
|
|
while next_arg options_one_by_line_ option_; do
|
|
|
|
options_[$i_]="$option_"
|
|
|
|
i_=$(($i_ + 1))
|
|
|
|
done
|
|
|
|
|
|
|
|
# autres paramètres
|
|
|
|
while [ -n "$1" ]; do
|
|
|
|
! get_option "$1" "votre_choix titre_du_menu choix_par_defaut" _ && break
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
|
|
|
c_=0
|
|
|
|
while true; do
|
|
|
|
if [ "$c_" == "0" ]; then
|
|
|
|
# Afficher le menu
|
|
|
|
[ -n "$titre_du_menu_" ] && tooenc "=== $titre_du_menu_ ==="
|
|
|
|
i_=1
|
|
|
|
for option_ in "${options_[@]}"; do
|
|
|
|
if [ "$option_" == "$choix_par_defaut_" ]; then
|
|
|
|
echo "$i_*- $option_"
|
|
|
|
else
|
|
|
|
echo "$i_ - $option_"
|
|
|
|
fi
|
2015-08-20 07:58:17 +04:00
|
|
|
i_=$(($i_ + 1))
|
2013-08-27 15:14:44 +04:00
|
|
|
done
|
|
|
|
fi
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
# Afficher les choix
|
|
|
|
if [ -n "$votre_choix_" ]; then
|
|
|
|
tooenc_ "$votre_choix_"
|
|
|
|
else
|
|
|
|
tooenc_ "Entrez le numéro de l'option choisie" "$UTF8"
|
|
|
|
fi
|
|
|
|
echo_ ": "
|
|
|
|
uread choice_
|
|
|
|
|
|
|
|
# valeur par défaut
|
|
|
|
if [ -z "$choice_" -a -n "$choix_par_defaut_" ]; then
|
|
|
|
choice_option_="$choix_par_defaut_"
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
# vérifier la saisie
|
|
|
|
choice_option_="$(expr "$choice_" : "[ $tab_]*\([0-9]*\)")"
|
|
|
|
if [ -n "$choice_option_" ] && [ "$choice_option_" -gt "0" -a "$choice_option_" -le "${#options_[*]}" ]; then
|
|
|
|
# numéro d'option correct
|
|
|
|
choice_option_="${options_[$(($choice_option_ - 1))]}"
|
|
|
|
break
|
|
|
|
else
|
|
|
|
OENC="$UTF8" eerror "Numéro d'option incorrect"
|
|
|
|
fi
|
|
|
|
|
|
|
|
c_=$(($c_ + 1))
|
|
|
|
if [ "$c_" == "5" ]; then
|
|
|
|
echo "" # sauter une ligne toutes les 4 tentatives
|
|
|
|
c_=0
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
set_var "$option_varname_" "$choice_option_"
|
|
|
|
}
|
|
|
|
|
|
|
|
function actions_menu() {
|
|
|
|
# $1=action_varname, $2=option_varname
|
|
|
|
# $3=actions (séparées par des espaces), $4=options (une par ligne)
|
|
|
|
# $5..*=action_quitter:, action_par_defaut:, actions_vides:, votre_choix:,
|
|
|
|
# titre_du_menu:, message_sans_options:
|
|
|
|
|
|
|
|
# Afficher un menu dont les membres sont les lignes de $options. Sur
|
|
|
|
# chacunes de ces entrées de menu, les actions de $actions peuvent être
|
|
|
|
# appliquées. Un choix doit être saisi sous la forme [action]num_option. Si
|
|
|
|
# action n'est pas précisé, il s'agit de l'action par défaut qui est
|
|
|
|
# sélectionnée. Par défaut, action_par_defaut est la première action, et
|
|
|
|
# action_quitter (qui provoque la sortie du menu sans choix) est la dernière
|
|
|
|
# action
|
|
|
|
|
|
|
|
# actions est une chaine d'éléments de la forme "k:Description" séparés par
|
|
|
|
# des espaces, où k est un lettre, et Description une description de
|
|
|
|
# l'action. Dans la chaine Description, les caractères '_' sont remplacés
|
|
|
|
# par des espaces pour l'affichage
|
|
|
|
|
|
|
|
# l'action choisie est placée dans la variable $action_varname. l'option
|
|
|
|
# choisie est placée dans la variable $option_varname
|
|
|
|
|
|
|
|
# note: les variables locales sont suffixées de _ pour éviter que
|
|
|
|
# $action_varname ou $option_varname soient égals à une des variables
|
|
|
|
# locales.
|
|
|
|
|
|
|
|
local tab_=" " # contient une tabulation
|
|
|
|
local i_ c_ error_displayed_
|
|
|
|
local options_one_by_line_ options_ option_
|
|
|
|
local actions_sep_by_space_ actions_ action_ action_key_ action_name_ action_names_
|
|
|
|
local actions_vides_ action_vide_
|
|
|
|
local action_quitter_
|
|
|
|
local action_par_defaut_
|
|
|
|
local choice_ choice_ok_ choice_action_ choice_option_
|
|
|
|
local action_varname_ option_varname_
|
|
|
|
local sans_options_ message_sans_options_
|
|
|
|
|
|
|
|
action_varname_="$1"; shift
|
|
|
|
option_varname_="$1"; shift
|
|
|
|
if [ -z "$action_varname_" -o -z "$option_varname_" ]; then
|
|
|
|
OENC="$UTF8" eerror "action_varname et option_varname doivent être spécifiés"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# actions possibles
|
|
|
|
actions_sep_by_space_="$1"; shift
|
|
|
|
if [ -z "$actions_sep_by_space_" ]; then
|
|
|
|
OENC="$UTF8" eerror "actions doit être non vide"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Construire le tableau des options
|
|
|
|
options_one_by_line_="$1"; shift
|
|
|
|
if [ -n "$options_one_by_line_" ]; then
|
|
|
|
i_=0
|
|
|
|
while next_arg options_one_by_line_ option_; do
|
|
|
|
options_[$i_]="$option_"
|
|
|
|
i_=$(($i_ + 1))
|
|
|
|
done
|
|
|
|
else
|
|
|
|
sans_options_=1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# autres paramètres
|
|
|
|
while [ -n "$1" ]; do
|
|
|
|
! get_option "$1" "actions_vides action_quitter action_par_defaut votre_choix titre_du_menu message_sans_options" _ && break
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
if [ -n "$sans_options_" -a -z "$actions_vides_" ]; then
|
|
|
|
OENC="$UTF8" eerror "options doit être non vide"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Construire le tableau des actions
|
|
|
|
i_=0
|
|
|
|
for action_ in $actions_sep_by_space_; do
|
|
|
|
action_key_="$(first_char "$action_")"
|
|
|
|
action_="$(last_chars "$action_")"
|
|
|
|
if [ "$(first_char "$action_")" == ":" ]; then
|
|
|
|
action_name_="$(last_chars "$action_")"
|
|
|
|
action_name_="${action_name_//_/ }"
|
|
|
|
else
|
|
|
|
action_name_="$action_key_"
|
|
|
|
fi
|
|
|
|
|
|
|
|
[ -z "$action_par_defaut_" ] && action_par_defaut_="$action_key_"
|
|
|
|
[ "$action_key_" == "$action_par_defaut_" ] && action_name_="$action_name_*"
|
|
|
|
action_names_="${action_names_:+$action_names_/}$action_name_"
|
|
|
|
|
|
|
|
actions_[$i_]="$(echo $action_key_ | awk '{print tolower($0)}')"
|
|
|
|
i_=$(($i_ + 1))
|
|
|
|
done
|
|
|
|
[ -z "$action_quitter_" ] && action_quitter_="$action_key_"
|
|
|
|
if [ "$action_par_defaut_" == "$action_quitter_" ]; then
|
|
|
|
OENC="$UTF8" eerror "action_par_defaut et action_quitter doivent être différents"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
actions_vides_="$actions_vides_ $action_quitter_"
|
|
|
|
|
|
|
|
# Lecture des choix de l'utilisateur
|
|
|
|
c_=0
|
|
|
|
while true; do
|
|
|
|
if [ "$c_" == "0" ]; then
|
|
|
|
# Afficher le menu
|
|
|
|
[ -n "$titre_du_menu_" ] && tooenc "=== $titre_du_menu_ ==="
|
|
|
|
if [ -z "$sans_options_" ]; then
|
|
|
|
i_=1
|
|
|
|
for option_ in "${options_[@]}"; do
|
|
|
|
tooenc "$i_ - $option_"
|
|
|
|
i_=$(($i_ + 1))
|
|
|
|
done
|
|
|
|
else
|
|
|
|
if [ -n "$message_sans_options_" ]; then
|
|
|
|
tooenc "$message_sans_options_"
|
|
|
|
else
|
|
|
|
tooenc "Pas d'options disponibles" "$UTF8"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
# Afficher les choix
|
|
|
|
tooenc_ "
|
|
|
|
Actions disponibles: " "$UTF8"
|
|
|
|
tooenc "$action_names_"
|
|
|
|
if [ -n "$votre_choix_" ]; then
|
|
|
|
tooenc_ "$votre_choix_"
|
|
|
|
else
|
|
|
|
tooenc_ "Entrez le numéro de l'option choisie" "$UTF8"
|
|
|
|
fi
|
|
|
|
echo_ ": "
|
|
|
|
read choice_
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
# vérifier la saisie
|
|
|
|
choice_option_="$(expr "$choice_" : "\([0-9]*\)")"
|
|
|
|
if [ -n "$choice_option_" ]; then
|
|
|
|
# on a donné le numéro de l'option sans l'action. retourner l'action par défaut
|
|
|
|
if [ -z "$sans_options_" -a "$choice_option_" -gt "0" -a "$choice_option_" -le "${#options_[*]}" ]; then
|
|
|
|
# numéro d'option correct
|
|
|
|
choice_option_="${options_[$(($choice_option_ - 1))]}"
|
|
|
|
choice_action_="$action_par_defaut_"
|
|
|
|
break
|
|
|
|
else
|
|
|
|
OENC="$UTF8" eerror "Numéro d'option incorrect"
|
|
|
|
fi
|
|
|
|
|
|
|
|
else
|
|
|
|
choice_action_="$(expr "$choice_" : "\([^ $tab_]\)")"
|
|
|
|
choice_ok_=
|
|
|
|
error_displayed_=
|
|
|
|
for action_ in "${actions_[@]}"; do
|
|
|
|
if [ "$choice_action_" == "$action_" ]; then
|
|
|
|
# action correcte
|
|
|
|
|
|
|
|
# est-ce une action vide (une action qui ne requière pas de numéro d'option)
|
|
|
|
for action_vide_ in $actions_vides_; do
|
|
|
|
if [ "$choice_action_" == "$action_vide_" ]; then
|
|
|
|
# retourner comme option tous les arguments de
|
|
|
|
# l'action vide, en trimant les espaces de début
|
|
|
|
choice_option_="$(expr "$choice_" : "[^ $tab_][ $tab_]*\(.*\)")"
|
|
|
|
choice_ok_=1
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
[ -n "$choice_ok_" ] && break
|
|
|
|
|
|
|
|
# lire le numéro d'option associé à l'action
|
|
|
|
choice_option_="$(expr "$choice_" : "[^ $tab_][ $tab_]*\([0-9]*\)")"
|
|
|
|
if [ -n "$choice_option_" ] && [ "$choice_option_" -gt "0" -a "$choice_option_" -le "${#options_[*]}" ]; then
|
|
|
|
# numéro d'option correct
|
|
|
|
choice_option_="${options_[$(($choice_option_ - 1))]}"
|
|
|
|
choice_ok_=1
|
|
|
|
else
|
|
|
|
OENC="$UTF8" eerror "Il faut spécifier un numéro d'option correct avec l'action"
|
|
|
|
error_displayed_=1
|
|
|
|
fi
|
|
|
|
[ -n "$choice_ok_" ] && break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
[ -n "$choice_ok_" ] && break
|
|
|
|
[ -z "$error_displayed_" ] && OENC="$UTF8" eerror "Action incorrecte"
|
|
|
|
fi
|
|
|
|
|
|
|
|
c_=$(($c_ + 1))
|
|
|
|
if [ "$c_" == "5" ]; then
|
|
|
|
echo "" # sauter une ligne toutes les 4 tentatives
|
|
|
|
c_=0
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
set_var "$action_varname_" "$choice_action_"
|
|
|
|
set_var "$option_varname_" "$choice_option_"
|
|
|
|
}
|
|
|
|
|
|
|
|
##################################################
|
|
|
|
# fileopts: opérations sur les fichiers
|
|
|
|
|
|
|
|
function file_get_vars() {
|
|
|
|
# lire les variables dans un fichier
|
|
|
|
local OENC="$UTF8"
|
|
|
|
local done_ prefix_ whole_file_ file_ vars_ var_ script_
|
|
|
|
|
|
|
|
# traiter les arguments
|
|
|
|
done_=
|
|
|
|
while [ -z "$done_" ]; do
|
|
|
|
case "$1" in
|
|
|
|
--prefix|-p)
|
|
|
|
# prefixe pour la variable
|
|
|
|
prefix_="$2"
|
|
|
|
shift; shift
|
|
|
|
;;
|
|
|
|
--whole-file|-w)
|
|
|
|
# lire les variables dans le fichier en entier, et pas seulement
|
|
|
|
# dans l'en-tête.
|
|
|
|
whole_file_=1
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
done_=1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
# obtenir le nom du fichier
|
|
|
|
file_="$1"; shift
|
|
|
|
if [ ! -f "$file_" ]; then
|
|
|
|
# fichier inexistant
|
|
|
|
ewarn "Fichier inexistant: $file_"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# initialiser les valeurs par défaut
|
|
|
|
vars_=
|
|
|
|
while [ -n "$1" ]; do
|
|
|
|
var_="$1"; shift
|
|
|
|
vars_="${vars_:+$vars_ }$var_"
|
|
|
|
set_var "$var_" "$1"; shift
|
|
|
|
done
|
|
|
|
|
|
|
|
# puis parcourir le fichier pour initialiser la valeur définitive des
|
|
|
|
# variables
|
|
|
|
if [ -z "$whole_file_" ]; then
|
|
|
|
script_="/^ *$/ { exit }
|
|
|
|
"
|
|
|
|
fi
|
|
|
|
|
|
|
|
for var_ in $vars_; do
|
|
|
|
script_="$script_
|
|
|
|
"'$0 ~ "^ *#* *" prefix "'"$var_"'=" {
|
|
|
|
# enlever les caractères inutiles
|
|
|
|
sub(" *#* *" prefix "'"$var_"'=", "")
|
|
|
|
# enlever éventuellement les quotes autour de la valeur
|
|
|
|
if ($0 ~ /^".*" *$/) {
|
|
|
|
$0 = substr($0, 2) # premier quote
|
|
|
|
match($0, /" *$/)
|
|
|
|
$0 = substr($0, 1, RSTART - 1) # dernier quote
|
|
|
|
}
|
|
|
|
# remplacer dans les valeurs les occurences de quotes
|
|
|
|
gsub("\"", "\\\"")
|
|
|
|
# afficher la ligne à évaluer
|
|
|
|
print "'"$var_"'=\"" $0 "\""
|
|
|
|
}
|
|
|
|
'
|
|
|
|
done
|
|
|
|
|
|
|
|
eval "$(uawk -v prefix="$prefix_" "$script_" <"$file_")"
|
|
|
|
}
|
|
|
|
|
|
|
|
function file_set_vars() {
|
|
|
|
# écrire les variables dans un fichier. Le fichier *doit exister*
|
|
|
|
local OENC="$UTF8"
|
|
|
|
local done_ quote_ comment_ prefix_ whole_file_ file_ var_ script_
|
|
|
|
|
|
|
|
# traiter les arguments
|
|
|
|
done_=
|
|
|
|
while [ -z "$done_" ]; do
|
|
|
|
case "$1" in
|
|
|
|
--quote-always|-q)
|
|
|
|
# toujours mettre les valeurs entre quotes
|
|
|
|
quote_=1
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
--comment-prefix|-c)
|
|
|
|
# commentaire à préfixer
|
|
|
|
comment_="$2"
|
|
|
|
shift; shift
|
|
|
|
;;
|
|
|
|
--prefix|-p)
|
|
|
|
# prefixe pour la variable
|
|
|
|
prefix_="$2"
|
|
|
|
shift; shift
|
|
|
|
;;
|
|
|
|
--whole-file|-w)
|
|
|
|
# écrire les variables dans le fichier en entier, et pas seulement
|
|
|
|
# dans l'en-tête.
|
|
|
|
whole_file_=1
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
done_=1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
# obtenir le nom du fichier
|
|
|
|
file_="$1"; shift
|
|
|
|
if [ ! -f "$file_" ]; then
|
|
|
|
# fichier inexistant
|
|
|
|
ewarn "Fichier inexistant: $file_"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# puis parcourir le fichier pour mettre à jour les valeurs
|
|
|
|
script_='BEGIN {
|
|
|
|
# faut-il mettre à jour les variables?
|
|
|
|
update_vars = 1'
|
|
|
|
for var_ in "$@"; do
|
|
|
|
script_="$script_
|
|
|
|
${var_}_done = 0"
|
|
|
|
done
|
|
|
|
script_="$script_
|
|
|
|
}"
|
|
|
|
|
|
|
|
script_="$script_"'
|
|
|
|
function quote_value_maybe(value) {
|
|
|
|
if (quote_always || index(value, " ") != 0) {
|
|
|
|
return "\"" value "\""
|
|
|
|
} else {
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function write_all_remaining_vars() {'
|
|
|
|
for var_ in "$@"; do
|
|
|
|
value="${!var_}"
|
|
|
|
script_="$script_"'
|
|
|
|
if (! '"$var_"'_done) {
|
|
|
|
print comment prefix "'"$var_"'=" quote_value_maybe("'"${value//\"/\\\"}"'")
|
|
|
|
'"$var_"'_done = 1
|
|
|
|
}'
|
|
|
|
done
|
|
|
|
script_="$script_
|
|
|
|
}"
|
|
|
|
|
|
|
|
if [ -z "$whole_file_" ]; then
|
|
|
|
script_="$script_"'
|
|
|
|
/^[ \t]*$/ {
|
|
|
|
write_all_remaining_vars()
|
|
|
|
update_vars = 0
|
|
|
|
}'
|
|
|
|
fi
|
|
|
|
|
|
|
|
script_="$script_"'
|
|
|
|
update_vars && comment == "" && $0 ~ "^ *#* *.*=.*$" {
|
|
|
|
#comment = gensub("^( *#* *).*=.*$", "\\1", 1)
|
|
|
|
comment = ""
|
|
|
|
if (match($0, /^ *#* */) != 0) {
|
|
|
|
comment = substr($0, RSTART, RLENGTH)
|
|
|
|
}
|
|
|
|
}'
|
|
|
|
|
|
|
|
for var_ in "$@"; do
|
|
|
|
value="${!var_}"
|
|
|
|
script_="$script_"'
|
|
|
|
update_vars && ! '"$var_"'_done && $0 ~ "^ *#* *" prefix "'"$var_"'=" {
|
|
|
|
#$0 = gensub("^( *#* *" prefix "'"$var_"'=).*$", "\\1", 1)
|
|
|
|
match($0, "^ *#* *" prefix "'"$var_"'=")
|
|
|
|
$0 = substr($0, RSTART, RLENGTH)
|
|
|
|
$0 = $0 quote_value_maybe("'"${value//\"/\\\"}"'")
|
|
|
|
print
|
|
|
|
'"$var_"'_done = 1
|
|
|
|
next
|
|
|
|
}'
|
|
|
|
done
|
|
|
|
|
|
|
|
script_="$script_"'
|
|
|
|
{
|
|
|
|
print
|
|
|
|
}
|
|
|
|
END {
|
|
|
|
if (update_vars) {
|
|
|
|
write_all_remaining_vars()
|
|
|
|
}
|
|
|
|
}'
|
|
|
|
|
|
|
|
uawk -v quote_always="$quote_" -v comment="$comment_" -v prefix="$prefix_" "$script_" <"$file_" >"$file_.$$" &&
|
|
|
|
/bin/mv "$file_.$$" "$file_"
|
|
|
|
}
|
|
|
|
|
|
|
|
function file_get_properties() {
|
|
|
|
# lire les propriétés d'un fichier de propriété java ou xml
|
|
|
|
if endswith "$1" .xml; then
|
|
|
|
file_get_xml_properties "$@"
|
|
|
|
else
|
|
|
|
file_get_java_properties "$@"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function file_set_properties() {
|
|
|
|
# écrire les propriétés d'un fichier de propriété java ou xml
|
|
|
|
local done_ create_
|
|
|
|
while [ -z "$done_" ]; do
|
|
|
|
case "$1" in
|
|
|
|
--create|-c)
|
|
|
|
create_=1
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
done_=1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
if endswith "$1" .xml; then
|
|
|
|
file_set_xml_properties ${create_:+-c} "$@"
|
|
|
|
else
|
|
|
|
file_set_java_properties ${create_:+-c} "$@"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function file_get_java_properties() {
|
|
|
|
# lire les propriétés d'un fichier de propriétés java. note: les noms de
|
|
|
|
# propriété java peuvent contenir le caractère "." mais pas les noms de
|
|
|
|
# variable bash. La conversion est faite automatiquement. Par exemple::
|
|
|
|
# file_get_properties build.properties path.to.package "default value"
|
|
|
|
# charge la valeur de la propriété dans la variable path_to_package
|
|
|
|
|
|
|
|
# $1=nom du fichier de propriété
|
|
|
|
# $2..n=propriétés qu'il faut lire et valeurs par défaut de ces propriétés
|
|
|
|
# $__2*i __=nom de la propriété
|
|
|
|
# $__2*i+1__=valeur par défaut de la propriété si la valeur n'existe pas
|
|
|
|
# dans le fichier
|
|
|
|
local OENC="$UTF8"
|
|
|
|
local file_="$1"; shift
|
|
|
|
if [ ! -f "$file_" ]; then
|
|
|
|
# fichier inexistant
|
|
|
|
ewarn "Fichier de propriété inexistant: $file_"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
local var_ sh_var_ awk_var_
|
|
|
|
local script
|
|
|
|
while [ -n "$1" ]; do
|
|
|
|
# pour chacune des variables...
|
|
|
|
var_="$1"; shift
|
|
|
|
sh_var_="${var_//./_}" # nom de la variable shell traduite ("." --> "_")
|
|
|
|
sh_var_="${sh_var_//-/_}" # ("-" --> "_")
|
|
|
|
awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
|
|
|
|
|
|
|
|
# initialiser la valeur par défaut
|
|
|
|
set_var "$sh_var_" "$1"; shift
|
|
|
|
|
|
|
|
# et créer le script qui affichera sa valeur
|
|
|
|
script="$script"'
|
|
|
|
$0 ~ "^[ \t]*'"$(quote_awk "$awkre_var_")"'=" {
|
|
|
|
# enlever les caractères de début
|
|
|
|
sub("^[ \t]*'"$(quote_awk "$awkre_var_")"'=", "")
|
|
|
|
value = $0
|
|
|
|
# éventuellement ajouter les lignes de continuation
|
|
|
|
while (substr(value, length(value), 1) == "\\") {
|
|
|
|
getline
|
|
|
|
sub("^[ \t]*", "")
|
|
|
|
value = substr(value, 1, length(value) - 1) $0
|
|
|
|
}
|
|
|
|
gsub("\"", "\\\"", value)
|
|
|
|
print "'"$sh_var_"'=\"" value "\""
|
|
|
|
}
|
|
|
|
'
|
|
|
|
done
|
|
|
|
|
|
|
|
eval "$(awk "$script" <"$file_")"
|
|
|
|
}
|
|
|
|
|
|
|
|
function file_set_java_properties() {
|
|
|
|
# écrire des propriétés dans un fichier de propriétés java.
|
|
|
|
|
|
|
|
# $1=nom du fichier de propriété
|
|
|
|
# $2..n=propriétés qu'il faut écrire et valeurs de ces propriétés
|
|
|
|
# $__2*i __=nom de la propriété
|
|
|
|
# $__2*i+1__=valeur de la propriété
|
|
|
|
# traiter les arguments
|
|
|
|
local OENC="$UTF8"
|
|
|
|
local done_ create_
|
|
|
|
while [ -z "$done_" ]; do
|
|
|
|
case "$1" in
|
|
|
|
--create|-c)
|
|
|
|
# créer le fichier s'il n'existe pas
|
|
|
|
create_=1
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
done_=1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
local file_="$1"; shift
|
|
|
|
if [ ! -f "$file_" ]; then
|
|
|
|
if [ -n "$create_" ]; then
|
|
|
|
touch "$file_"
|
|
|
|
else
|
|
|
|
# fichier inexistant
|
|
|
|
ewarn "Fichier de propriété inexistant: $file_"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
# récupérer les noms des propriétés et leur valeur
|
|
|
|
local var_ arg_ sh_var_ awkre_var_ value_
|
|
|
|
local -a vars_ values_
|
|
|
|
value_=vars_
|
|
|
|
for arg_ in "$@"; do
|
|
|
|
array_add "$value_" "$arg_"
|
|
|
|
if [ "$value_" == "vars_" ]; then
|
|
|
|
value_=values_
|
|
|
|
else
|
|
|
|
value_=vars_
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
# créer le script qui va parcourir le fichier pour mettre à jour les valeurs
|
|
|
|
script_="BEGIN {"
|
|
|
|
for var_ in "${vars_[@]}"; do
|
|
|
|
sh_var_="${var_//./_}" # nom de la variable shell traduite ("." --> "_")
|
|
|
|
sh_var_="${sh_var_//-/_}" # ("-" --> "_")
|
|
|
|
script_="$script_
|
|
|
|
${sh_var_}_done = 0"
|
|
|
|
done
|
|
|
|
script_="$script_"'
|
|
|
|
}
|
|
|
|
function write_all_remaining_vars() {'
|
|
|
|
local i=0
|
|
|
|
while [ $i -lt ${#vars_[*]} ]; do
|
|
|
|
var_="${vars_[$i]}"
|
|
|
|
sh_var_="${var_//./_}" # nom de la variable shell traduite ("." --> "_")
|
|
|
|
sh_var_="${sh_var_//-/_}" # ("-" --> "_")
|
|
|
|
awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
|
|
|
|
value_="${values_[$i]}"
|
|
|
|
|
|
|
|
script_="$script_"'
|
|
|
|
if (! '"$sh_var_"'_done) {
|
|
|
|
print "'"$var_"'=" "'"${value_//\"/\\\"}"'"
|
|
|
|
'"$sh_var_"'_done = 1
|
|
|
|
}'
|
|
|
|
i=$((i + 1))
|
|
|
|
done
|
|
|
|
script_="$script_
|
|
|
|
}"
|
|
|
|
|
|
|
|
local i=0
|
|
|
|
while [ $i -lt ${#vars_[*]} ]; do
|
|
|
|
var_="${vars_[$i]}"
|
|
|
|
sh_var_="${var_//./_}" # nom de la variable shell traduite ("." --> "_")
|
|
|
|
sh_var_="${sh_var_//-/_}" # ("-" --> "_")
|
|
|
|
awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
|
|
|
|
value_="${values_[$i]}"
|
|
|
|
script_="$script_"'
|
|
|
|
! '"$sh_var_"'_done && $0 ~ "^[ \t]*'"$awkre_var_"'=" {
|
|
|
|
#name = gensub("^([ \t]*'"$awkre_var_"'=).*$", "\\1", 1)
|
|
|
|
match($0, "^[ \t]*'"$awkre_var_"'=")
|
|
|
|
name = substr($0, RSTART, RLENGTH)
|
|
|
|
value = substr($0, length(name) + 1)
|
|
|
|
|
|
|
|
while (substr(value, length(value), 1) == "\\") {
|
|
|
|
getline
|
|
|
|
value = value $0
|
|
|
|
}
|
|
|
|
line = name "'"${value_//\"/\\\"}"'"
|
|
|
|
prefix = ""
|
|
|
|
max_len = 75
|
|
|
|
if (length(line) > max_len) {
|
|
|
|
do {
|
|
|
|
print prefix substr(line, 1, max_len) "\\"
|
|
|
|
line = substr(line, max_len + 1)
|
|
|
|
prefix = " "
|
|
|
|
max_len = 71
|
|
|
|
} while (length(line) > max_len)
|
|
|
|
}
|
|
|
|
print prefix line
|
|
|
|
'"$sh_var_"'_done = 1
|
|
|
|
next
|
|
|
|
}'
|
|
|
|
i=$((i + 1))
|
|
|
|
done
|
|
|
|
|
|
|
|
script_="$script_
|
|
|
|
{
|
|
|
|
print
|
|
|
|
}
|
|
|
|
END {
|
|
|
|
write_all_remaining_vars()
|
|
|
|
}"
|
|
|
|
|
|
|
|
awk "$script_" <"$file_" >"$file_.$$" &&
|
|
|
|
/bin/mv "$file_.$$" "$file_"
|
|
|
|
}
|
|
|
|
|
|
|
|
function file_get_xml_properties() {
|
|
|
|
# lire les propriétés d'un fichier de propriétés xml. Limitation: les
|
|
|
|
# propriétés ne doivent pas être continuées sur plusieurs lignes. Les
|
|
|
|
# propriétés doivent être écrites sous la forme::
|
|
|
|
# <propname>propvalue</propname>
|
|
|
|
|
|
|
|
# note: les noms de propriété java peuvent contenir le caractère "." mais
|
|
|
|
# pas les noms de variable bash. La conversion est faite
|
|
|
|
# automatiquement. Par exemple::
|
|
|
|
# file_get_properties build.properties path.to.package "default value"
|
|
|
|
# charge la valeur de la propriété dans la variable path_to_package
|
|
|
|
|
|
|
|
# $1=nom du fichier de propriété
|
|
|
|
# $2..n=propriétés qu'il faut lire et valeurs par défaut de ces propriétés
|
|
|
|
# $__2*i __=nom de la propriété
|
|
|
|
# $__2*i+1__=valeur par défaut de la propriété si la valeur n'existe pas
|
|
|
|
# dans le fichier
|
|
|
|
local OENC="$UTF8"
|
|
|
|
local file_="$1"; shift
|
|
|
|
if [ ! -f "$file_" ]; then
|
|
|
|
# fichier inexistant
|
|
|
|
ewarn "Fichier de propriété inexistant: $file_"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
local var_ sh_var_ awk_var_
|
|
|
|
local script
|
|
|
|
while [ -n "$1" ]; do
|
|
|
|
# pour chacune des variables...
|
|
|
|
var_="$1"; shift
|
|
|
|
sh_var_="${var_//./_}" # nom de la variable shell traduite ("." --> "_")
|
|
|
|
sh_var_="${sh_var_//-/_}" # ("-" --> "_")
|
|
|
|
awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
|
|
|
|
|
|
|
|
# initialiser la valeur par défaut
|
|
|
|
set_var "$sh_var_" "$1"; shift
|
|
|
|
|
|
|
|
# et créer le script qui affichera sa valeur
|
|
|
|
script="$script"'
|
|
|
|
$0 ~ /^[ \t]*<'"$awkre_var_"'>.*<\/'"$awkre_var_"'>/ {
|
|
|
|
sub(/^[ \t]*<'"$awkre_var_"'>/, "")
|
|
|
|
sub(/<\/'"$awkre_var_"'>.*$/, "")
|
|
|
|
gsub("\"", "\\\"", $0)
|
|
|
|
print "'"$sh_var_"'=\"" $0 "\""
|
|
|
|
}
|
|
|
|
'
|
|
|
|
done
|
|
|
|
|
|
|
|
eval "$(awk "$script" <"$file_")"
|
|
|
|
}
|
|
|
|
|
|
|
|
function file_set_xml_properties() {
|
|
|
|
# écrire des propriétés dans un fichier de propriétés java.
|
|
|
|
|
|
|
|
# $1=nom du fichier de propriété
|
|
|
|
# $2..n=propriétés qu'il faut écrire et valeurs de ces propriétés
|
|
|
|
# $__2*i __=nom de la propriété
|
|
|
|
# $__2*i+1__=valeur de la propriété
|
|
|
|
# traiter les arguments
|
|
|
|
local OENC="$UTF8"
|
|
|
|
local done_ create_
|
|
|
|
while [ -z "$done_" ]; do
|
|
|
|
case "$1" in
|
|
|
|
--create|-c)
|
|
|
|
# créer le fichier s'il n'existe pas
|
|
|
|
create_=1
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
done_=1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
local file_="$1"; shift
|
|
|
|
if [ ! -f "$file_" ]; then
|
|
|
|
if [ -n "$create_" ]; then
|
|
|
|
touch "$file_"
|
|
|
|
else
|
|
|
|
# fichier inexistant
|
|
|
|
ewarn "Fichier de propriété inexistant: $file_"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
# récupérer les noms des propriétés et leur valeur
|
|
|
|
local var_ arg_ sh_var_ awkre_var_ value_
|
|
|
|
local -a vars_ values_
|
|
|
|
value_=vars_
|
|
|
|
for arg_ in "$@"; do
|
|
|
|
array_add "$value_" "$arg_"
|
|
|
|
if [ "$value_" == "vars_" ]; then
|
|
|
|
value_=values_
|
|
|
|
else
|
|
|
|
value_=vars_
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
# créer le script qui va parcourir le fichier pour mettre à jour les valeurs
|
|
|
|
script_='BEGIN {
|
|
|
|
rootElement = ""'
|
|
|
|
for var_ in "${vars_[@]}"; do
|
|
|
|
sh_var_="${var_//./_}" # nom de la variable shell traduite ("." --> "_")
|
|
|
|
sh_var_="${sh_var_//-/_}" # ("-" --> "_")
|
|
|
|
script_="$script_
|
|
|
|
${sh_var_}_done = 0"
|
|
|
|
done
|
|
|
|
script_="$script_"'
|
|
|
|
}
|
|
|
|
function write_all_remaining_vars() {'
|
|
|
|
local i=0
|
|
|
|
while [ $i -lt ${#vars_[*]} ]; do
|
|
|
|
var_="${vars_[$i]}"
|
|
|
|
sh_var_="${var_//./_}" # nom de la variable shell traduite ("." --> "_")
|
|
|
|
sh_var_="${sh_var_//-/_}" # ("-" --> "_")
|
|
|
|
awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
|
|
|
|
value_="${values_[$i]}"
|
|
|
|
|
|
|
|
script_="$script_"'
|
|
|
|
if (! '"$sh_var_"'_done) {
|
|
|
|
print "<'"$var_"'>'"${value_//\"/\\\"}"'</'"$var_"'>"
|
|
|
|
'"$sh_var_"'_done = 1
|
|
|
|
}'
|
|
|
|
i=$((i + 1))
|
|
|
|
done
|
|
|
|
script_="$script_
|
|
|
|
}"'
|
|
|
|
rootElement == "" {
|
|
|
|
match($0, /<.*>/)
|
|
|
|
element = substr($0, RSTART + 1, RLENGTH - 2)
|
|
|
|
firstChar = substr(element, 1, 1)
|
|
|
|
if (firstChar != "?" && firstChar != "!") {
|
|
|
|
rootElement = element
|
|
|
|
}
|
|
|
|
}'
|
|
|
|
|
|
|
|
local i=0
|
|
|
|
while [ $i -lt ${#vars_[*]} ]; do
|
|
|
|
var_="${vars_[$i]}"
|
|
|
|
sh_var_="${var_//./_}" # nom de la variable shell traduite ("." --> "_")
|
|
|
|
sh_var_="${sh_var_//-/_}" # ("-" --> "_")
|
|
|
|
awkre_var_="${var_//./\\\\.}" # nom de la variable pour une expression régulière awk
|
|
|
|
value_="${values_[$i]}"
|
|
|
|
script_="$script_"'
|
|
|
|
rootElement != "" && ! '"$sh_var_"'_done && $0 ~ /^[ \t]*<'"$awkre_var_"'>.*<\/'"$awkre_var_"'>/ {
|
|
|
|
match($0, /^[ \t]*<'"$awkre_var_"'>/)
|
|
|
|
first = substr($0, RSTART, RLENGTH)
|
|
|
|
value = substr($0, length(first) + 1)
|
|
|
|
match(value, /<\/'"$awkre_var_"'>.*$/)
|
|
|
|
last = substr(value, RSTART, RLENGTH)
|
|
|
|
value = substr(value, 1, RSTART)
|
|
|
|
|
|
|
|
print first "'"${value_//\"/\\\"}"'" last
|
|
|
|
'"$sh_var_"'_done = 1
|
|
|
|
next
|
|
|
|
}'
|
|
|
|
i=$((i + 1))
|
|
|
|
done
|
|
|
|
|
|
|
|
script_="$script_"'
|
|
|
|
rootElement != "" && $0 ~ "</" rootElement ">" {
|
|
|
|
rootElement = ""
|
|
|
|
write_all_remaining_vars()
|
|
|
|
}
|
|
|
|
{
|
|
|
|
print
|
|
|
|
}
|
|
|
|
END {
|
|
|
|
write_all_remaining_vars()
|
|
|
|
}'
|
|
|
|
|
|
|
|
awk "$script_" <"$file_" >"$file_.$$" &&
|
|
|
|
/bin/mv "$file_.$$" "$file_"
|
|
|
|
}
|
|
|
|
|
|
|
|
##################################################
|
|
|
|
# date: fonction pour afficher la date en français et au format RFC-822
|
|
|
|
|
|
|
|
function get_date_rfc822() {
|
|
|
|
if [ -n "$__legacy_date__" ]; then
|
|
|
|
LC_TIME=C date +"%a, %d %b %Y %H:%M:%S %Z"
|
|
|
|
else
|
|
|
|
date -R
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_date_fr() {
|
|
|
|
date +"%d/%m/%Y"
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_time_fr() {
|
|
|
|
date +"%Hh%M"
|
|
|
|
}
|
|
|
|
|
|
|
|
function parse_date() {
|
|
|
|
local value="$1" type="${2:-date}"
|
|
|
|
local now="$(awk 'BEGIN { print mktime(strftime("%Y %m %d 00 00 00 +0400")) }')"
|
|
|
|
case "$value" in
|
|
|
|
+*)
|
|
|
|
value="$(($now + ${value#+} * 86400))"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
value="$(<<<"$value" awk -F/ '{
|
|
|
|
nd = strftime("%d"); nm = strftime("%m"); ny = strftime("%Y")
|
|
|
|
d = $1 + 0; if (d < 1 || d > 31) d = nd;
|
|
|
|
if ($2 == "") m = nm;
|
|
|
|
else { m = $2 + 0; if (m < 1 || m > 12) m = nm; }
|
|
|
|
if ($3 == "") y = ny;
|
|
|
|
else { y = $3 + 0; if (y < 100) y = y + 2000; }
|
|
|
|
print mktime(sprintf("%04i %02i %02i 00 00 00 +0400", y, m, d));
|
|
|
|
}')"
|
|
|
|
esac
|
|
|
|
case "$type" in
|
|
|
|
d|date)
|
|
|
|
awk '{ print strftime("%d/%m/%Y", $0 + 0) }' <<<"$value"
|
|
|
|
;;
|
|
|
|
l|ldap)
|
|
|
|
awk '{ print strftime("%Y%m%d%H%M%S+0400", $0 + 0) }' <<<"$value"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "$value"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
##################################################
|
|
|
|
# path: fonctions pour gérer les chemins
|
|
|
|
|
|
|
|
function abspath() {
|
|
|
|
# Retourner un chemin absolu vers $1. Si $2 est non nul et si $1 est un
|
|
|
|
# chemin relatif, alors $1 est exprimé par rapport à $2, sinon il est
|
|
|
|
# exprimé par rapport au répertoire courant.
|
|
|
|
local pwd="$(pwd)"
|
|
|
|
if [ -n "$2" ]; then
|
|
|
|
# tout d'abord, calculer le répertoire à partir duquel on exprime les
|
|
|
|
# chemin relatifs
|
|
|
|
if [ -d "$2" ]; then
|
|
|
|
pwd="$(cd "$2"; pwd)"
|
|
|
|
else
|
|
|
|
pwd="$(abspath "$2")"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -e "$1" ]; then
|
|
|
|
local dn="$(dirname "$1")" bn="$(basename "$1")"
|
|
|
|
if [ "$bn" == "." ]; then
|
|
|
|
echo "$(cd "$pwd"; cd "$dn"; pwd)"
|
|
|
|
elif [ "$bn" == ".." ]; then
|
|
|
|
echo "$(cd "$pwd"; cd "$dn/.."; pwd)"
|
|
|
|
elif [ "$dn" == "/" ]; then
|
|
|
|
echo "/$bn"
|
|
|
|
else
|
|
|
|
echo "$(cd "$pwd"; cd "$dn"; pwd)/$bn"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
if first_char_is "$1" "/"; then
|
|
|
|
echo "$1"
|
|
|
|
else
|
|
|
|
echo "$pwd/$1"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function relpath() {
|
|
|
|
# Retourner le chemin relatif de $1 par rapport à $2. Si $2 n'est pas
|
|
|
|
# spécifié, on prend le répertoire courant. Si $1 ou $2 ne sont pas des
|
|
|
|
# répertoires absolus, il sont transformés en chemins absolus par rapport à
|
|
|
|
# $3.
|
|
|
|
# Si $1==$2, retourner une chaine vide
|
|
|
|
local p="$(abspath "$1" "$3")" cwd="$2"
|
|
|
|
if [ -z "$cwd" ]; then
|
|
|
|
cwd="$(pwd)"
|
|
|
|
else
|
|
|
|
cwd="$(abspath "$cwd" "$3")"
|
|
|
|
fi
|
|
|
|
if [ "$p" == "$cwd" ]; then
|
|
|
|
echo ""
|
|
|
|
elif [ "${p#$cwd/}" != "$p" ]; then
|
|
|
|
echo "${p#$cwd/}"
|
|
|
|
else
|
|
|
|
local rp
|
|
|
|
while [ -n "$cwd" -a "${p#$cwd/}" == "$p" ]; do
|
|
|
|
rp="${rp:+$rp/}.."
|
|
|
|
cwd="${cwd%/*}"
|
|
|
|
done
|
|
|
|
rp="$rp/${p#$cwd/}"
|
|
|
|
# ${rp%//} traite le cas $1==/
|
|
|
|
echo "${rp%//}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function deref() {
|
|
|
|
# Retourner un chemin absolu vers le fichier $1, dans lequel
|
|
|
|
# toutes les composantes "lien symbolique" ont été supprimées.
|
|
|
|
local OENC="$UTF8"
|
|
|
|
|
|
|
|
local max_deref=50
|
|
|
|
local file="$1"
|
|
|
|
while [ -L "$file" ]; do
|
|
|
|
basedir="$(dirname "$file")"
|
|
|
|
link="$(readlink "$file")"
|
|
|
|
if first_char_is "$link" "/"; then
|
|
|
|
# lien absolu
|
|
|
|
file="$link"
|
|
|
|
else
|
|
|
|
# lien relatif
|
|
|
|
file="$basedir/$link"
|
|
|
|
fi
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
max_deref=$(($max_deref - 1))
|
|
|
|
[ $max_deref -eq 0 ] && die "Plus de 50 indirection. Le lien $file est-il récursif?"
|
|
|
|
done
|
|
|
|
abspath "$file"
|
|
|
|
}
|
|
|
|
|
|
|
|
function path_if_test() {
|
|
|
|
# afficher un chemin si le fichier $2 existe (en utilisant l'opérateur $1)
|
|
|
|
# dans l'un des chemins absolus $4..n. si $3==relative, afficher le chemin
|
|
|
|
# relatif, sinon le chemin absolu. note: $3 peut être de la forme
|
|
|
|
# relative:path, auquel cas le chemin affiché est exprimé relativement à
|
|
|
|
# path
|
|
|
|
local op_="$1"; shift
|
|
|
|
local file_="$1"; shift
|
|
|
|
local rel_="$1" reldir_=; shift
|
|
|
|
if beginswith "$rel_" relative; then
|
|
|
|
reldir_="${rel_#relative}"
|
|
|
|
if beginswith "$reldir_" :; then
|
|
|
|
# on a un argument de la forme relative:path
|
|
|
|
reldir_="${reldir_#:}"
|
|
|
|
if [ -n "$reldir_" ]; then
|
|
|
|
reldir_="${reldir_}/"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
# argument vide ou format non valide
|
|
|
|
reldir_=
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
rel_=
|
|
|
|
fi
|
|
|
|
|
|
|
|
while [ -n "$1" ]; do
|
|
|
|
local basedir_="$1"
|
|
|
|
if [ $op_ "$basedir_/$file_" ]; then
|
|
|
|
if [ -n "$rel_" ]; then
|
|
|
|
echo "$reldir_$file_"
|
|
|
|
else
|
|
|
|
echo "$basedir_/$file_"
|
|
|
|
fi
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
function is_archive() {
|
|
|
|
# tester si l'extension d'un fichier indique que c'est une archive
|
|
|
|
local name="${1%.zip}"
|
|
|
|
name="${name%.tgz}"
|
|
|
|
name="${name%.tar.gz}"
|
|
|
|
name="${name%.tar}"
|
|
|
|
name="${name%.tar.bz2}"
|
|
|
|
name="${name%.jar}"
|
|
|
|
name="${name%.war}"
|
|
|
|
name="${name%.ear}"
|
|
|
|
[ "$name" != "$1" ]
|
|
|
|
}
|
|
|
|
function extract_archive() {
|
|
|
|
# Extraire le contenu de l'archive $1 dans le répertoire ${2:-.}
|
|
|
|
# Les autres arguments indiquent les fichiers à extraire
|
|
|
|
local arch="$1" destdir="${2:-.}"
|
|
|
|
shift; shift
|
|
|
|
if endswith "$arch" .zip; then
|
|
|
|
unzip -d "$destdir" "$arch" "$@" || return
|
|
|
|
elif endswith "$arch" .tgz || endswith "$arch" .tar.gz; then
|
|
|
|
tar xzf "$arch" -C "$destdir" "$@" || return
|
|
|
|
elif endswith "$arch" .tbz2 || endswith "$arch" .tar.bz2; then
|
|
|
|
tar xjf "$arch" -C "$destdir" "$@" || return
|
|
|
|
elif endswith "$arch" .tar; then
|
|
|
|
tar xf "$arch" -C "$destdir" "$@" || return
|
|
|
|
elif endswith "$arch" .jar || endswith "$arch" .war || endswith "$arch" .ear; then
|
|
|
|
jar xf "$arch" -C "$destdir" "$@" || return
|
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
##################################################
|
|
|
|
# array: fonctions pour gérer des tableaux
|
|
|
|
|
|
|
|
# Afficher la commande permettant d'initialiser le tableau $1 avec les valeurs:
|
|
|
|
# soit du tableau $2, soit de $3..$n si $2=="@"
|
|
|
|
# S'il n'y a que l'argument $1, alors afficher la commande permettant de
|
|
|
|
# recréer le tableau $1
|
|
|
|
function set_array_cmd() {
|
|
|
|
[ $# -eq 1 ] && set -- "$1" "$1"
|
|
|
|
local s_ v_ f_
|
|
|
|
s_="$1=("; shift
|
|
|
|
if [ "$1" == "@" ]; then
|
|
|
|
shift
|
|
|
|
else
|
|
|
|
eval "set -- \"\${$1[@]}\""
|
|
|
|
fi
|
|
|
|
f_=1
|
|
|
|
for v_ in "$@"; do
|
|
|
|
[ -n "$f_" ] && f_= || s_="$s_ "
|
|
|
|
s_="$s_\"$(quote_arg "$v_")\""
|
|
|
|
done
|
|
|
|
s_="$s_)"
|
|
|
|
echo "$s_"
|
|
|
|
}
|
|
|
|
# Soit $1 un tableau à créer. Si $2=="@", créer le tableau $1 avec les valeurs
|
|
|
|
# $3..$n. Sinon, créer le tableau $1 avec les valeurs du tableau $2.
|
|
|
|
# Cette fonction n'existe que comme un pendant de set_var(), mais le véritable
|
|
|
|
# intérêt est la fonction set_array_cmd(). cf array_copy() pour une version plus
|
|
|
|
# efficace de la copie de tableaux
|
|
|
|
function set_array() {
|
|
|
|
eval "$(set_array_cmd "$@")"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_count() {
|
|
|
|
# retourner le nombre d'éléments du tableau $1
|
|
|
|
eval "echo \${#$1[*]}"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_isempty() {
|
|
|
|
# tester si un tableau est vide
|
|
|
|
test $(array_count "$1") -eq 0
|
|
|
|
}
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
function array_new() {
|
|
|
|
# créer un tableau vide dont le nom est $1
|
|
|
|
eval "$1=()"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_add() {
|
|
|
|
# ajouter la valeur $2 au tableau dont le nom est $1
|
|
|
|
eval "$1=(\"\${$1[@]}\" \"$(quote_arg "$2")\")"
|
|
|
|
}
|
|
|
|
|
|
|
|
# insérer la valeur $2 au début du tableau dont le nom est $1
|
|
|
|
function array_ins() { eval "$1=(\"$(quote_arg "$2")\" \"\${$1[@]}\")"; }
|
|
|
|
|
|
|
|
function array_add_values() {
|
|
|
|
# Ajouter les valeurs $2 au tableau dont le nom est $1
|
|
|
|
# $2 est une liste de valeurs séparées par des espaces ou le caractère ':'
|
|
|
|
local array_="$1" value_
|
|
|
|
if [[ "$2" == *:* ]]; then
|
|
|
|
local IFS=:
|
|
|
|
set -- $2
|
|
|
|
unset IFS
|
|
|
|
else
|
|
|
|
set -- $2
|
|
|
|
fi
|
|
|
|
for value_ in "$@"; do
|
|
|
|
array_add "$array_" "$value_"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_del() {
|
|
|
|
# supprimer les valeurs $2 du tableau dont le nom est $1
|
|
|
|
local arg_="$(quote_arg "$2")" value_
|
|
|
|
local -a array_
|
|
|
|
eval 'for value_ in "${'"$1"'[@]}"; do if [ "$value_" != "'"$arg_"'" ]; then array_add array_ "$value_"; fi; done'
|
|
|
|
array_copy "$1" array_
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_set() {
|
|
|
|
# ajouter la valeur $2 au tableau dont le nom est $1, si la valeur n'y est
|
|
|
|
# pas déjà. Retourner vrai si la valeur a été ajoutée
|
|
|
|
local value_="$(quote_arg "$2")" i_
|
|
|
|
eval "for i_ in \"\${$1[@]}\"; do if [ \"\$i_\" == \"$value_\" ]; then return 1; fi; done"
|
|
|
|
array_add "$1" "$2"
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_contains() {
|
|
|
|
# tester si le tableau dont le nom est $1 contient la valeur $2
|
|
|
|
local value_="$(quote_arg "$2")" i_
|
|
|
|
eval "for i_ in \"\${$1[@]}\"; do if [ \"\$i_\" == \"$value_\" ]; then return; fi; done"
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_copy() {
|
|
|
|
# copier le contenu du tableau $2 dans le tableau $1
|
|
|
|
eval "$1=(\"\${$2[@]}\")"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_extend() {
|
|
|
|
# Ajouter le contenu du tableau $2 au tableau $1
|
|
|
|
eval "$1=(\"\${$1[@]}\" \"\${$2[@]}\")"
|
|
|
|
}
|
|
|
|
# dans le tableau $1, remplacer toutes les occurences de $2 par $3..*
|
|
|
|
function array_replace() {
|
|
|
|
local srcname_="$1"; shift
|
|
|
|
local from_="$1"; shift
|
|
|
|
local -a dest_
|
|
|
|
local src_ v_
|
|
|
|
src_="$srcname_[@]"
|
|
|
|
for value_ in "${!src_}"; do
|
|
|
|
if [ "$value_" == "$from_" ]; then
|
|
|
|
dest_=("${dest_[@]}" "$@")
|
|
|
|
else
|
|
|
|
dest_=("${dest_[@]}" "$value_")
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
array_copy "$srcname_" dest_
|
|
|
|
}
|
|
|
|
# Pour chacune des valeurs 'v' du tableau $1, appeler la fonction $2 avec les
|
|
|
|
# arguments '$v $3..$n'
|
|
|
|
function array_each() {
|
|
|
|
local an_="$1"; shift
|
|
|
|
local f_="$1"; shift
|
|
|
|
local a_="$an_[@]" v
|
|
|
|
for v_ in "${!a_}"; do
|
|
|
|
"$f_" "$v_" "$@"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
# retourner la première valeur du tableau $1
|
|
|
|
function first_value() { eval "echo \"\${$1[@]:0:1}\""; }
|
|
|
|
# retourner la dernière valeur du tableau $1
|
|
|
|
function last_value() { eval "echo \"\${$1[@]:\$((-1)):1}\""; }
|
|
|
|
# copier le contenu du tableau $2 dans le tableau $1
|
|
|
|
function array_copy() { eval "$1=(\"\${$2[@]}\")"; }
|
|
|
|
# copier tous les valeurs du tableau $2(=$1) dans le tableau $1, excepté la dernière
|
|
|
|
function array_copy_firsts() { eval "$1=(\"\${${2:-$1}[@]:0:\$((\${#${2:-$1}[@]}-1))}\")"; }
|
|
|
|
function array_del_last() { array_copy_firsts "$1"; }
|
|
|
|
# copier tous les valeurs du tableau $2(=$1) dans le tableau $1, excepté la première
|
|
|
|
function array_copy_lasts() { eval "$1=(\"\${${2:-$1}[@]:1}\")"; }
|
|
|
|
function array_del_first() { array_copy_lasts "$1"; }
|
|
|
|
# ajouter le contenu du tableau $2 au tableau $1
|
|
|
|
function array_extend() { eval "$1=(\"\${$1[@]}\" \"\${$2[@]}\")"; }
|
|
|
|
# ajouter toutes les valeurs du tableau $2 dans le tableau $1, excepté la dernière
|
|
|
|
function array_extend_firsts() { eval "$1=(\"\${$1[@]}\" \"\${$2[@]:0:\$((\${#$2[@]}-1))}\")"; }
|
|
|
|
# ajouter toutes les valeurs du tableau $2 dans le tableau $1, excepté la première
|
|
|
|
function array_extend_lasts() { eval "$1=(\"\${$1[@]}\" \"\${$2[@]:1}\")"; }
|
|
|
|
# Pour chacune des valeurs 'v' du tableau $1, appeler la fonction $2 avec les
|
|
|
|
# arguments '$v $3..$n', et remplacer la valeur par le résultat de la fonction
|
|
|
|
function array_map() {
|
|
|
|
local an_="$1"; shift
|
|
|
|
local f_="$1"; shift
|
|
|
|
local a_="$an_[@]" v
|
|
|
|
local -a vs_
|
|
|
|
for v_ in "${!a_}"; do
|
|
|
|
vs_=("${vs_[@]}" "$("$f_" "$v_" "$@")")
|
|
|
|
done
|
|
|
|
array_copy "$an_" vs_
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_from_args() {
|
|
|
|
# créer le tableau dont le nom est $1 avec les arguments à partir de $2
|
|
|
|
local array_="$1"; shift
|
|
|
|
eval "$array_"'=("$@")'
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_from_file() {
|
|
|
|
# créer le tableau dont le nom est $1 avec les lignes du fichier $2
|
|
|
|
# si $3=all, ne pas supprimer les lignes vide ou de commentaire
|
|
|
|
eval "$(<"$2" uawk -v name="$1" -v all="$3" '
|
|
|
|
BEGIN {
|
|
|
|
print name "=("
|
|
|
|
}
|
|
|
|
all != "all" && $0 ~ /^$/ { next }
|
|
|
|
all != "all" && $0 ~ /^#/ { next }
|
|
|
|
{
|
|
|
|
gsub(/'\''/, "'\'\\\\\'\''")
|
|
|
|
print "'\''" $0 "'\''"
|
|
|
|
}
|
|
|
|
END {
|
|
|
|
print ")"
|
|
|
|
}')" #"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_from_lines() {
|
|
|
|
# créer le tableau $1 avec chaque ligne de $2. Les lignes vides sont
|
|
|
|
# ignorés.
|
|
|
|
eval "$(<<<"$2" uawk -v name="$1" '
|
|
|
|
BEGIN {
|
|
|
|
print name "=("
|
|
|
|
}
|
|
|
|
/^$/ { next }
|
|
|
|
{
|
|
|
|
gsub(/'\''/, "'\'\\\\\'\''")
|
|
|
|
print "'\''" $0 "'\''"
|
|
|
|
}
|
|
|
|
END {
|
|
|
|
print ")"
|
|
|
|
}')" #"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_split() {
|
|
|
|
# créer le tableau $1 avec chaque élément de $2 (un ensemble d'éléments
|
|
|
|
# séparés par $3, qui vaut ':' par défaut). Les éléments vides sont
|
|
|
|
# ignorés. par exemple "a::b" est équivalent à "a:b"
|
|
|
|
eval "$(<<<"$2" uawk -v RS="" -v ORS="" '{ gsub("\r*\n$", ""); print }' |
|
|
|
|
uawk -v name="$1" -v RS="${3:-:}" '
|
|
|
|
BEGIN {
|
|
|
|
print name "=("
|
|
|
|
}
|
|
|
|
/^$/ { next }
|
|
|
|
{
|
|
|
|
gsub(/'\''/, "'\'\\\\\'\''")
|
|
|
|
print "'\''" $0 "'\''"
|
|
|
|
}
|
|
|
|
END {
|
|
|
|
print ")"
|
|
|
|
}')" #"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_from_path() {
|
|
|
|
array_split "$1" "$2" ":"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_join() {
|
|
|
|
# afficher le contenu du tableau dont le nom est $1 sous forme d'une liste
|
|
|
|
# de chemins séparés par $2
|
|
|
|
# Si $1=="@", alors les éléments du tableaux sont les arguments de la
|
|
|
|
# fonction à partir de $3
|
|
|
|
# Si $1!="@" et que le tableau est vide, afficher $3
|
|
|
|
# Si $1!="@", $4 et $5 sont des préfixes et suffixes à rajouter à chaque élément
|
|
|
|
local array_ line_ joined_ sep_="${2:-,}" pfix_ sfix_
|
|
|
|
if [ "$1" == "@" ]; then
|
|
|
|
array_="\$@"
|
|
|
|
shift; shift
|
|
|
|
else
|
|
|
|
array_="\${$1[@]}"
|
|
|
|
pfix_="$4"
|
|
|
|
sfix_="$5"
|
|
|
|
fi
|
|
|
|
eval 'for line_ in "'"$array_"'"; do joined_="${joined_:+$joined_'"$sep_"'}$pfix_$line_$sfix_"; done'
|
|
|
|
if [ -n "$joined_" ]; then
|
|
|
|
echo "$joined_"
|
|
|
|
elif [ "$array_" != "\$@" -a -n "$3" ]; then
|
|
|
|
echo "$3"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_to_lines() {
|
|
|
|
# afficher le tableau dont le nom est $1 sous forme de lignes
|
|
|
|
array_join "$1" "
|
|
|
|
" "$2" "$3" "$4"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_to_path() {
|
|
|
|
# afficher le tableau dont le nom est $1 sous forme d'une liste de chemins
|
|
|
|
# séparés par ':')
|
|
|
|
array_join "$1" ":" "$2" "$3" "$4"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_enum_start() {
|
|
|
|
# Commencer l'énumération du tableau $1
|
|
|
|
[ -z "$1" ] && return 1
|
|
|
|
set_var_literal "${1}_enum_index" 0
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_enum_next() {
|
|
|
|
# Soit la variable array dont le nom est donné dans $1, et la variable next
|
|
|
|
# dont le nom est donné dans $2. Mettre à jour next avec l'élément
|
|
|
|
# $1_enum_index du tableau array, supprimer cet élément, et incrémenter
|
|
|
|
# $1_enum_index. Retourner faux s'il n'y a plus d'éléments dans le tableau
|
|
|
|
|
|
|
|
local arrayname_="$1" varname_="$2"
|
|
|
|
[ -z "$arrayname_" -o -z "$varname_" ] && return 1
|
|
|
|
|
|
|
|
eval "local count_=\${#$arrayname_[*]}"
|
|
|
|
[ $count_ -eq 0 ] && return 1
|
|
|
|
|
|
|
|
# calculer l'index de départ
|
|
|
|
local index_="${arrayname_}_enum_index"
|
|
|
|
[ -z "${!index_}" ] && set_var_literal "$index_" 0
|
|
|
|
# lire la valeur
|
|
|
|
local item_="$arrayname_[${!index_}]"
|
|
|
|
set_var "$varname_" "${!item_}"
|
|
|
|
# la supprimer du tableau
|
|
|
|
unset "$item_"
|
|
|
|
# incrémenter le compteur
|
|
|
|
set_var_literal "$index_" $((${!index_} + 1))
|
|
|
|
}
|
|
|
|
|
|
|
|
function __array_ls() {
|
|
|
|
# Lister les fichiers avec `list_$1 $3 $4...`, et les mettre dans le tableau $2
|
|
|
|
# Le tableau contient les chemins complets, par seulement les noms comme avec list_$1
|
|
|
|
local list_="list_${1:-all}"; shift
|
|
|
|
local arrayname_="$1"; shift
|
|
|
|
local basedir_="${1:-.}"; shift
|
|
|
|
local -a files_
|
|
|
|
array_from_lines files_ "$("$list_" "$basedir_" "$@")"
|
|
|
|
local file_
|
|
|
|
array_new "$arrayname_"
|
|
|
|
for file_ in "${files_[@]}"; do
|
|
|
|
array_add "$arrayname_" "$basedir_/$file_"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_lsall() {
|
|
|
|
# Lister les fichiers avec `list_all $2 $3...`, et les mettre dans le tableau $1
|
|
|
|
# Le tableau contient les chemins complets, par seulement les noms comme avec list_all
|
|
|
|
__array_ls all "$@"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_lsdirs() {
|
|
|
|
# Lister les fichiers avec `list_dirs $2 $3...`, et les mettre dans le tableau $1
|
|
|
|
# Le tableau contient les chemins complets, par seulement les noms comme avec list_dirs
|
|
|
|
__array_ls dirs "$@"
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_lsfiles() {
|
|
|
|
# Lister les fichiers avec `list_files $2 $3...`, et les mettre dans le tableau $1
|
|
|
|
# Le tableau contient les chemins complets, par seulement les noms comme avec list_files
|
|
|
|
__array_ls files "$@"
|
|
|
|
}
|
|
|
|
|
|
|
|
##################################################
|
|
|
|
# Accès à une resource web
|
|
|
|
|
|
|
|
function _dumpurl_method_available() {
|
|
|
|
# $1=dumpurl_method
|
|
|
|
local m="$1"
|
|
|
|
if [ "$m" == "curl" ]; then
|
|
|
|
progexists curl || [ -n "$__curl_EXISTS__" ]
|
|
|
|
elif [ "$m" == "wget" ]; then
|
|
|
|
if progexists wget || [ -n "$__wget_EXISTS__" ]; then
|
|
|
|
# vérifier la version ce doit être >= 1.9
|
|
|
|
wget --version | grep "^GNU Wget" | awk '{
|
|
|
|
v = $0
|
|
|
|
major = 0
|
|
|
|
minor = 0
|
|
|
|
if (match(v, /[0-9][0-9]*/) != 0) {
|
|
|
|
major = substr(v, RSTART, RLENGTH) + 0
|
|
|
|
v = substr(v, RSTART + RLENGTH + 1)
|
|
|
|
}
|
|
|
|
if (match(v, /[0-9][0-9]*/) != 0) {
|
|
|
|
minor = substr(v, RSTART, RLENGTH) + 0
|
|
|
|
v = substr(v, RSTART + RLENGTH + 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (major >= 1 && minor >= 9) {
|
|
|
|
exit 0
|
|
|
|
} else {
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
}'
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function dumpurl_method() {
|
|
|
|
if [ -z "$DUMPURL_METHOD" ]; then
|
|
|
|
local DUMPURL_METHOD
|
|
|
|
if _dumpurl_method_available curl; then
|
|
|
|
DUMPURL_METHOD=curl
|
|
|
|
elif _dumpurl_method_available wget; then
|
|
|
|
DUMPURL_METHOD=wget
|
|
|
|
## XXX telnet non supporté pour le moment
|
|
|
|
#elif progexists telnet; then
|
|
|
|
# DUMPURL_METHOD=telnet
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
echo "$DUMPURL_METHOD"
|
|
|
|
}
|
|
|
|
|
|
|
|
function dumpurl_available() {
|
|
|
|
# retourner vrai si dumpurl est disponible (si wget ou curl sont trouvés)
|
|
|
|
_dumpurl_method_available "$(dumpurl_method)"
|
|
|
|
}
|
|
|
|
|
|
|
|
function dumpurl() {
|
|
|
|
# afficher le résultat du téléchargement de l'url $1, ou une chaine vide si
|
|
|
|
# une erreur s'est produite.
|
|
|
|
# l'option -m choisit la méthode: GET ou POST (suivi de la chaine à envoyer)
|
|
|
|
# l'option -H permet d'ajouter des en-têtes
|
|
|
|
|
|
|
|
local done= http_method=GET postdata headers header url no_proxy
|
|
|
|
local -a headers
|
|
|
|
while [ -n "$1" ]; do
|
|
|
|
case "$1" in
|
|
|
|
--)
|
|
|
|
shift
|
|
|
|
done=1
|
|
|
|
;;
|
|
|
|
|
|
|
|
-m)
|
|
|
|
shift
|
|
|
|
http_method="$1"
|
|
|
|
if [ "$http_method" == "POST" ]; then
|
|
|
|
postdata="$2"
|
|
|
|
shift
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
|
|
|
|
-H)
|
|
|
|
shift
|
|
|
|
array_add headers "$1: $2"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
|
|
|
|
-X)
|
|
|
|
no_proxy=1
|
|
|
|
;;
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
-*)
|
|
|
|
#ewarn "option non reconnue: $1"
|
|
|
|
;;
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
*)
|
|
|
|
done=1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
[ -n "$done" ] && break
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
url="$1"
|
|
|
|
|
|
|
|
dumpurl_available || return 1
|
|
|
|
local dumpurl_method="$(dumpurl_method)"
|
|
|
|
|
|
|
|
if [ "$dumpurl_method" == "curl" ]; then
|
|
|
|
curl="curl${no_proxy:+ -x ''}"
|
|
|
|
for header in "${headers[@]}"; do
|
|
|
|
curl="$curl --header \"$(quote_arg "$header")\""
|
|
|
|
done
|
|
|
|
if [ "$http_method" == "GET" ]; then
|
|
|
|
:
|
|
|
|
elif [ "$http_method" == "POST" ]; then
|
|
|
|
curl="$curl --data-binary \"$(quote_arg "$postdata")\""
|
|
|
|
else
|
|
|
|
# méthode inconnue
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
curl="$curl -f -s \"$(quote_arg "$url")\""
|
|
|
|
|
|
|
|
eval "$curl"
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
elif [ "$dumpurl_method" == "wget" ]; then
|
|
|
|
wget="wget${no_proxy:+ --no-proxy}"
|
|
|
|
for header in "${headers[@]}"; do
|
|
|
|
wget="$wget --header=\"$(quote_arg "$header")\""
|
|
|
|
done
|
|
|
|
if [ "$http_method" == "GET" ]; then
|
|
|
|
:
|
|
|
|
elif [ "$http_method" == "POST" ]; then
|
|
|
|
wget="$wget --post-data=\"$(quote_arg "$postdata")\""
|
|
|
|
else
|
|
|
|
# méthode inconnue
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
wget="$wget -q -O - \"$(quote_arg "$url")\""
|
|
|
|
|
|
|
|
eval "$wget"
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
# XXX pas encore implémenté
|
|
|
|
#elif [ "$dumpurl_method" == "telnet" ]; then
|
|
|
|
# return 1
|
|
|
|
|
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
}
|