diff --git a/lib/makeself-2.1.5/makeself-header.sh b/lib/makeself-2.1.5/makeself-header.sh index 6838dd7..e97a407 100755 --- a/lib/makeself-2.1.5/makeself-header.sh +++ b/lib/makeself-2.1.5/makeself-header.sh @@ -412,7 +412,7 @@ if test "\$keep" = n; then fi eval \$finish; if test x"\$tmp_archive" = xy; then - exec /bin/rm -f "\$thisarch" + /bin/rm -f "\$thisarch"; exit \$res else exit \$res fi diff --git a/lib/ulib/woinst b/lib/ulib/woinst index 0d3a7ca..3e2a9fd 100644 --- a/lib/ulib/woinst +++ b/lib/ulib/woinst @@ -410,27 +410,52 @@ OPTIONS PREFIX=value Spécifier une valeur pour un préfixe, plutôt que de laisser uprefix l'autodétecter. Utiliser uprefix -l pour une liste de préfixes valides. - -b Redémarrer les instances en mode bounce. - Par défaut, les instances sont arrêtées avant le déploiement, et - redémarrées après - -W Ne déployer que les resources web. Implique -n - -n Ne pas tagger les bundles déployés avec un numéro de version. Par - défaut, l'utilisateur est invité à compléter des informations telles - que n° de version et date de release si ces informations ne sont pas + --prefix + Corriger les chemins des variables qui commencent par des préfixes + valides (c'est la valeur par défaut). Utiliser 'uprefix -l' pour avoir + une liste de préfixes valides + --no-prefix + Ne jamais corriger un chemin. + -W, --webres + Ne déployer que les resources web. Implique -n + -n, --no-tag + Ne pas tagger les bundles déployés avec un numéro de version. En temps + normal, l'utilisateur est invité à compléter des informations telles que + n° de version et date de release si ces informations ne sont pas disponible. - -x CMD + -d, --active-dbconfig DBCONFIG + Spécifier le profil de connexion à utiliser par défaut pour tous les + eomodels du bundle. S'il faut un profil différent en fonction de l'eomodel, utiliser l'option -m + -m, --active-dbconfig-map EOMODEL:DBCONFIG + Spécifier un mapping entre un nom d'eomodel et le profil de connexion à + utiliser. Pour les eomodels qui ne sont pas spécifiés, la valeur par + défaut est utilisée si elle existe. Il est possible de spécifier + plusieurs mappings en les séparant par des virgules. + --stop-start + Redémarrer les instances de la manière classique: les instances sont + arrêtées avant le déploiement, et redémarrées après. C'est la valeur par + défaut. + -b, --bounce + Redémarrer les instances en mode bounce. + -x, --exec CMD Exécuter la commande CMD après avoir effectué le déploiement" } - local bounce webinst notag scripts istmpdir tmpdir - scripts=() + local istmpdir tmpdir autoprefix=1 bounce webinst notag default_dbconfig + local -a dbconfigs scripts parse_opts "${PRETTYOPTS[@]}" \ --help '$exit_with __woinst_display_help' \ - -b,--bounce bounce=1 \ - -W,--webres webinst=1 \ - -n,--notag notag=1 \ - -x:,--exec: scripts \ --is-tmpdir '$istmpdir=1; tmpdir=.' \ + --prefix autoprefix=1 \ + --no-prefix autoprefix= \ + -W,--webres webinst=1 \ + --tag notag= \ + -n,--no-tag notag=1 \ + -d:,--active-dbconfig: default_dbconfig= \ + -m:,--active-dbconfig-map: dbconfigs \ + --stop-start bounce= \ + -b,--bounce bounce=1 \ + -x:,--exec: scripts \ @ args -- "$@" && set -- "${args[@]}" || { eerror "$args" @@ -457,7 +482,8 @@ OPTIONS for src in "${@:-.}"; do if [[ "$src" == *=* ]]; then splitvar "$src" name value - array_add variables "$name" + array_addu variables "$name" + [ -n "$autoprefix" ] && value="$(expand_prefix "$value")" _setv "$name" "$value" else src="$(abspath "$src")" @@ -469,6 +495,19 @@ OPTIONS copied=1 fi if [ -d "$src" ]; then + setx name=basename -- "$src" + case "$src" in + *.woa|*.framework) ;; + *) # support projet maven + if [ ! -f "$src/pom.xml" ]; then + : # non, pas un projet maven + elif [ -d "$src/target/$name.woa" ]; then + src="$src/target/$name.woa" + elif [ -d "$src/target/$name.framework" ]; then + src="$src/target/$name.framework" + fi + ;; + esac if endswith "$src" .framework; then is_wofwkdir "$src" || { eerror "Framework invalide: $(ppath "$src")" @@ -504,6 +543,68 @@ OPTIONS done eend + # Corriger les eomodelds + array_fix_paths dbconfigs , + if [ -n "$default_dbconfig" -o ${#dbconfigs[*]} -gt 0 ]; then + etitle "Configuration des eomodels" + local -a eonames eomodels tmpeomodels + local eom dbc eoname eomodel dbconfig found + + estep "Calcul de la liste des eomodels" + if [ ${#dbconfigs[*]} -eq 0 ]; then + for src in "${frameworks[@]}"; do + array_from_lines tmpeomodels "$(find "$src" -type d -name "*.eomodeld")" + for eom in "${tmpeomodels[@]}"; do + array_addu eonames "$(basename -- "$eom")" + done + done + for src in "${applications[@]}"; do + array_from_lines tmpeomodels "$(find "$src" -type d -name "*.eomodeld")" + for eom in "${tmpeomodels[@]}"; do + array_addu eonames "$(basename -- "$eom")" + done + done + else + for dbc in "${dbconfigs[@]}"; do + splitpair "$dbc" eom dbc + [ "${eom%.eomodeld}" != "$eom" ] || eom="$eom.eomodeld" + array_addu eonames "$(basename -- "$eom")" + done + fi + for eom in "${eonames[@]}"; do + for src in "${frameworks[@]}"; do + array_from_lines tmpeomodels "$(find "$src" -type d -name "$eom")" + array_extendu eomodels tmpeomodels + done + for src in "${applications[@]}"; do + array_from_lines tmpeomodels "$(find "$src" -type d -name "$eom")" + array_extendu eomodels tmpeomodels + done + done + + for eomodel in "${eomodels[@]}"; do + setx eoname=basename -- "$eomodel" + if [ ! -f "$eomodel/index.eomodeld" ]; then + ewarn "$eomodel: eomode invalide" + continue + fi + found= + for dbc in "${dbconfigs[@]}"; do + splitpair "$dbc" eom dbconfig + [ "${eom%.eomodeld}" != "$eom" ] || eom="$eom.eomodeld" + if [ "$(basename -- "$eom")" == "$eoname" ]; then + found="$dbconfig" + break + fi + done + [ -z "$found" -a -n "$default_dbconfig" ] && found="$default_dbconfig" + if [ -n "$found" ]; then + estep "$eomodel [$found]" + sed -i "/^ *activeDatabaseConfigName *=/s/=.*;/=\"$found\";/" "$eomodel/index.eomodeld" + fi + done + fi + # Tagger les bundles if [ -z "$webinst" -a -z "$notag" ]; then etitle "Tagger les bundles" diff --git a/rtoinst b/rtoinst index e60140d..f6b4e2d 100755 --- a/rtoinst +++ b/rtoinst @@ -235,22 +235,24 @@ eend ## Déploiement -# sur l'hôte distant, ne rendre interactif qu'à partir de -yy +# sur l'hôte distant, ne rendre non interactif qu'à partir de -yy rinteraction=$__interaction [ $rinteraction -lt 2 ] && rinteraction=$(($rinteraction + 1)) for host in "${hosts[@]}"; do if [ "$host" == "localhost" ]; then - etitle -s "Déploiement sur l'hôte local" + etitle "Déploiement sur l'hôte local" "$archive" ${tmproot:+--tmproot "$tmproot"} -- "${webapps[@]}" "$@" "${toinst_options[@]}" eend else splituserhost "$host" user host [ -n "$user" ] || user=root - etitle -s "Déploiement sur $user@$host" + etitle "Déploiement sur $user@$host" + estep "Copie de l'archive" scp -S "$SSH" "$archive" "$user@$host:" || die + estep "Lancement du script de déploiement" "$SSH" -qt "$user@$host" "\ __interaction=$rinteraction @@ -259,6 +261,7 @@ __tlevel=$(qval "$__tlevel") export __interaction __estack __tlevel ${UTOOLS_LANG:+UTOOLS_LANG='$UTOOLS_LANG'; export UTOOLS_LANG }$(qvals "./$archivename" ${tmproot:+--tmproot "$tmproot"} -- "${webapps[@]}" "$@" "${toinst_options[@]}")" + eend fi done diff --git a/ruinst b/ruinst index 66691a4..4aa8dcd 100755 --- a/ruinst +++ b/ruinst @@ -222,7 +222,7 @@ fi ## Répertoires à déployer et hôtes sur lesquels faire le déploiement confirm_src= if [ $# -eq 0 ] || [[ "$1" == -* ]] || [[ "$1" == *=* ]]; then - # pas d'argument, ou c'est une option (qui fait donc partie des arguments de toinst) + # pas d'argument, ou c'est une option (qui fait donc partie des arguments de uinst) src=. confirm_src=1 else @@ -247,7 +247,7 @@ $(array_to_lines host "" " ")" fi if [ -n "$confirm_src" ]; then - # pas d'argument, ou c'est une option (qui fait donc partie des arguments de toinst) + # pas d'argument, ou c'est une option (qui fait donc partie des arguments de uinst) read_value "Entrez le répertoire à déployer" src "$src" O fi @@ -273,13 +273,14 @@ if [ -n "$make_archive" ]; then ac_set_tmpfile archive archivename="$(basename "$archive")" - etitle "Création de l'archive pour le déploiement" \ - "$scriptdir/mkusfx" --tmp-archive --self-contained -o "$archive" "$src" || die + etitle "Création de l'archive pour le déploiement" + "$scriptdir/mkusfx" --tmp-archive --self-contained -o "$archive" "$src" || die + eend fi ## Déploiement -# sur l'hôte distant, ne rendre interactif qu'à partir de -yy +# sur l'hôte distant, ne rendre non interactif qu'à partir de -yy rinteraction=$__interaction [ $rinteraction -lt 2 ] && rinteraction=$(($rinteraction + 1)) @@ -297,8 +298,10 @@ for host in "${hosts[@]}"; do [ -n "$user" ] || user=root etitle -s "Déploiement sur $user@$host" + estep "Copie de l'archive" scp -S "$SSH" "$archive" "$user@$host:" || die + estep "Lancement du script de déploiement" "$SSH" -qt "$user@$host" "\ __interaction=$rinteraction @@ -307,6 +310,7 @@ __tlevel=$(qval "$__tlevel") export __interaction __estack __tlevel ${UTOOLS_LANG:+UTOOLS_LANG='$UTOOLS_LANG'; export UTOOLS_LANG }$(qvals "./$archivename" ${tmproot:+--tmproot "$tmproot"} -- MYHOST="$host" "$@")" + eend fi done diff --git a/rwoinst b/rwoinst index e93484c..615adaa 100755 --- a/rwoinst +++ b/rwoinst @@ -9,6 +9,10 @@ function display_help() { USAGE $scriptname [-H host] [-T tmproot] ... [-- options de woinst] +note: à cause d'une limitation de makeself, les options de toinst ne devraient +pas contenir d'espaces ni de caractères spéciaux. L'échappement de ces +caractères n'est pas garanti. + OPTIONS -T, --tmproot TMPROOT Spécifier le répertoire temporaire sur l'hôte distant, comme par exemple @@ -18,7 +22,6 @@ OPTIONS Spécifier le programme à utiliser pour la connection par ssh. -h, --host hosts -h, --host @hostsfile - -H host Spécifier un ou plusieurs hôtes sur lequels faire le déploiement. Pour spécifier plusieurs hôtes, il est possible d'utiliser plusieurs fois l'option -h, ou spécifier en une seule fois plusieurs hôtes en les @@ -31,6 +34,17 @@ OPTIONS user@host, e.g -h user@host La forme @hostsfile permet de lire la liste des hôtes depuis le fichier hostsfile, à raison d'un hôte par ligne. + -w, -W, --whost host[:htdocs] + Comme --host, mais pour le déploiement des resources web. Contrairement + à --host, un seul hôte peut être spécifié par occurence de l'option, + pour permettre de spécifier éventuellement le répertoire vers lequel + copier les resources web. Ainsi, les deux commandes suivantes sont + équivalentes: + rwoinst -h host.tld -- -W HTDOCSDIR=HTDOCSBASE/wo + rwoinst -w host.tld:HTDOCSBASE/wo + Il est possible de spécifier en une seule invocation --host et --whost + pour déployer l'application sur un hôte et les resources web sur un + autre. --deploy --no-deploy Autoriser (respectivement interdire) l'utilisation de la configuration @@ -40,7 +54,10 @@ OPTIONS déploiement est interrogée pour avoir cette information. -c, --deploy-config CONFNAME Cette option permet de spécifier le nom de la configuration à utiliser - pour effectuer la requête. Par défaut, utiliser le nom 'rwoinst'" + pour effectuer la requête. Par défaut, utiliser le nom 'rwoinst' + -p, --deploy-profile PROFILE + Spécifier le profil à utiliser pour l'interrogation de la configuration + locale de déploiement. Par défaut, aucun profil n'est sélectionné." } __PARSED_HOSTS=() @@ -106,20 +123,65 @@ function fix_hosts() { array_map hosts __dot_is_localhost } +function deploy_to() { + local archive="$1" host="$2" tmproot="$3" + shift; shift; shift + + local r= + if [ "$host" == "localhost" ]; then + etitle "Sur l'hôte local" + "$archive" ${tmproot:+--tmproot "$tmproot"} -- "$@" || r=1 + eend + else + local user + local archivename="$(basename "$archive")" + + splituserhost "$host" user host + [ -n "$user" ] || user=root + + # sur l'hôte distant, ne rendre non interactif qu'à partir de -yy + rinteraction=$__interaction + [ $rinteraction -lt 2 ] && rinteraction=$(($rinteraction + 1)) + + etitle "Vers $user@$host" + + estep "Copie de l'archive" + scp -S "$SSH" "$archive" "$user@$host:" || r=1 + + if [ -z "$r" ]; then + estep "Lancement du script de déploiement" + "$SSH" -qt "$user@$host" "\ +__interaction=$rinteraction +__estack=$(qval "$__estack") +__tlevel=$(qval "$__tlevel") +export __interaction __estack __tlevel +${UTOOLS_LANG:+UTOOLS_LANG='$UTOOLS_LANG'; export UTOOLS_LANG +}$(qvals "./$archivename" ${tmproot:+--tmproot "$tmproot"} -- MYHOST="$host" "$@")" || r=1 + fi + + eend + fi + return ${r:-0} +} + action=deploy tmproot= SSH= hosts=() +whosts=() deploy_enable=1 deploy_confname=rwoinst +deploy_profile= parse_opts "${PRETTYOPTS[@]}" \ --help '$exit_with display_help' \ -T:,--tmproot: tmproot= \ -S:,--ssh: SSH= \ -h:,-H:,--host: hosts \ + -w:,-W:,--whost: whosts \ --deploy deploy_enable=1 \ --no-deploy deploy_enable= \ -c:,--deploy-config deploy_confname= \ + -p:,--deploy-profile: deploy_profile= \ @ args -- "$@" && set -- "${args[@]}" || die "$args" : "${SSH:=ssh}" @@ -127,7 +189,7 @@ parse_opts "${PRETTYOPTS[@]}" \ ## Bundle à déployer et hôtes sur lesquels faire le déploiement confirm_bundle= if [ $# -eq 0 ] || [[ "$1" == -* ]] || [[ "$1" == *=* ]]; then - # pas d'argument, ou c'est une option (qui fait donc partie des arguments de toinst) + # pas d'argument, ou c'est une option (qui fait donc partie des arguments de woinst) case "$(basename -- "$(pwd)")" in *.woa|*.framework) bundle=.;; *) bundle=;; @@ -137,16 +199,51 @@ else bundle="$1" fi +woinst_options=() if array_isempty hosts && [ -n "$deploy_enable" -a -n "$bundle" ]; then urequire deploy deploy_setconf "$deploy_confname" if deploy_loadconf; then setxx bundlename=abspath "$bundle" // basename -- - if eval "$(deploy_query -v host DEST wobundle rwoinst_bundle "" shell "$bundlename")"; then - check_interaction -c && einfo "$bundlename: ce bundle sera déployé vers les hôtes suivants: -$(array_to_lines host "" " ")" + host=(); bounce=; notag=; exec=; dbconfig=; dbconfigmap= + if eval "$(deploy_query -v host,bounce,notag,exec,dbconfig,dbconfigmap DEST wobundle rwoinst_bundle "$deploy_profile" shell "$bundlename")"; then + array_copy deploy_hosts host + deploy_options=() + [ -n "$bounce" ] && array_add deploy_options -b + [ -n "$notag" ] && array_add deploy_options -n + if [ -n "$exec" ]; then + for x in "${exec[@]}"; do + array_add deploy_options -x "$x" + done + fi + [ -n "$dbconfig" ] && array_add deploy_options -d "$dbconfig" + if [ -n "$dbconfigmap" ]; then + for m in "${dbconfigmap[@]}"; do + array_add deploy_options -m "$m" + done + fi + deploy_whosts=() + host=(); destdir= + if eval "$(deploy_query -v host,destdir DEST wobundle rwoinst_webres "$deploy_profile" shell "$bundlename")"; then + for wh in "${host[@]}"; do + array_add deploy_whosts "$wh:$destdir" + done + fi + msg="$bundlename: ce bundle sera déployé vers les hôtes suivants: +$(array_to_lines deploy_hosts "" " ")" + if [ ${#deploy_whosts[*]} -gt 0 -o ${#deploy_options[*]} -gt 0 ]; then + msg="$msg +avec le(s) paramètre(s) suivant(s):" + [ ${#deploy_whosts[*]} -gt 0 ] && msg="$msg +$(array_to_lines deploy_whosts "" " --whost ")" + [ ${#deploy_options[*]} -gt 0 ] && msg="$msg + $(qvals "${deploy_options[@]}")" + fi + check_interaction -c && einfo "$msg" ask_any "Voulez-vous continuer?" Oq || die - array_copy hosts host + array_extend hosts deploy_hosts + array_extend woinst_options deploy_options + array_extend whosts deploy_whosts if [ -n "$confirm_bundle" ]; then confirm_bundle= set -- "$bundle" "$@" @@ -156,7 +253,7 @@ $(array_to_lines host "" " ")" fi if [ -n "$confirm_bundle" ]; then - # pas d'argument, ou c'est une option (qui fait donc partie des arguments de toinst) + # pas d'argument, ou c'est une option (qui fait donc partie des arguments de woinst) read_value "Veuillez entrer la bundle à déployer" bundle "$bundle" O set -- "$bundle" "$@" fi @@ -165,8 +262,10 @@ array_isempty hosts && read_value "Entrez une liste d'hôtes séparés par ':'" fix_hosts ## Création de l'archive + etitle "Création du répertoire de travail" ac_set_tmpdir workdir + bundles=() while [ -n "$1" ]; do if [ "$1" == "--" ]; then @@ -184,6 +283,19 @@ while [ -n "$1" ]; do cp_R "$src" "$workdir" || die elif [ -d "$src" ]; then src="$(abspath "$src")" + setx srcname=basename -- "$src" + case "$src" in + *.woa|*.framework) ;; + *) # support projet maven + if [ ! -f "$src/pom.xml" ]; then + : # non, pas un projet maven + elif [ -d "$src/target/$srcname.woa" ]; then + src="$src/target/$srcname.woa" + elif [ -d "$src/target/$srcname.framework" ]; then + src="$src/target/$srcname.framework" + fi + ;; + esac if endswith "$src" .framework; then is_wofwkdir "$src" || die "Framework invalide: $(ppath "$src")" elif endswith "$src" .woa; then @@ -202,55 +314,34 @@ while [ -n "$1" ]; do done estep "Copie de l'environnement de déploiement" -ulibsync "$workdir" -echo '#!/bin/sh -# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 -if . `dirname "$0"`/ulib/ulibsh; then - urequire DEFAULTS woinst -else - exit 1 -fi -OENC="$UTF8" -woinst "$@"' >"$workdir/woinst" -chmod +x "$workdir/woinst" +mkdir "$workdir/lib" +ulibsync "$workdir/lib" +cp "$scriptdir/woinst.sh" "$workdir" +chmod +x "$workdir/woinst.sh" eend +etitle "Création de l'archive pour le déploiement" ac_set_tmpfile archive -archivename="$(basename "$archive")" -etitle "Création de l'archive pour le déploiement" \ - "$scriptdir/mkusfx" --bare --tmp-archive -o "$archive" "$workdir" -- ./woinst --is-tmpdir "${bundles[@]}" || die +"$scriptdir/mkusfx" --bare --tmp-archive -o "$archive" "$workdir" -- ./woinst.sh --is-tmpdir "${bundles[@]}" || die + +eend ## Déploiement -# sur l'hôte distant, ne rendre interactif qu'à partir de -yy -rinteraction=$__interaction -[ $rinteraction -lt 2 ] && rinteraction=$(($rinteraction + 1)) - +etitle "Déploiement des bundles" for host in "${hosts[@]}"; do - if [ "$host" == "localhost" ]; then - etitle "Déploiement sur l'hôte local" \ - "$archive" ${tmproot:+--tmproot "$tmproot"} -- "$@" - else - if [[ "$host" == *@* ]]; then - user="${host%%@*}" - host="${host#*@}" - else - user=root - fi - - etitle "Déploiement sur $user@$host" - estep "Copie de l'archive" - scp -S "$SSH" "$archive" "$user@$host:" || die - estep "Lancement du script de déploiement" - "$SSH" -qt "$user@$host" "\ -__interaction=$rinteraction -__estack=$(qval "$__estack") -__tlevel=$(qval "$__tlevel") -export __interaction __estack __tlevel -${UTOOLS_LANG:+UTOOLS_LANG='$UTOOLS_LANG'; export UTOOLS_LANG -}$(qvals "./$archivename" ${tmproot:+--tmproot "$tmproot"} -- MYHOST="$host" "$@")" - eend - fi + deploy_to "$archive" "$host" "$tmproot" "$@" "${woinst_options[@]}" || die done +eend + +if [ ${#whosts[*]} -gt 0 ]; then + etitle "Déploiement des resources web" + for hostdestdir in "${whosts[@]}"; do + splitpair "$hostdestdir" host destdir + deploy_to "$archive" "$host" "$tmproot" \ + -y -W ${destdir:+HTDOCSDIR="$destdir"} "$@" "${woinst_options[@]}" || die + done + eend +fi diff --git a/uinst b/uinst index 8401fa3..8f4fdde 100755 --- a/uinst +++ b/uinst @@ -1,6 +1,6 @@ #!/bin/bash # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 -source "$(dirname "$0")/lib/ulib/ulib" || exit 1 +source "$(dirname -- "$0")/lib/ulib/ulib" || exit 1 urequire DEFAULTS uinst uinst_nolocal "$@" diff --git a/uinst.sh b/uinst.sh index 7bf2408..cd15bff 100755 --- a/uinst.sh +++ b/uinst.sh @@ -2,7 +2,7 @@ # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 # Version de uinst qui fonctionne avec /bin/sh. Le contrôle est transmis à # bash, qui est recherché dans une liste de répertoires standards -. `dirname "$0"`/lib/ulib/ulibsh || exit 1 +. `dirname -- "$0"`/lib/ulib/ulibsh || exit 1 urequire DEFAULTS uinst uinst_nolocal "$@" diff --git a/woinst b/woinst index 482b8c6..14ec712 100755 --- a/woinst +++ b/woinst @@ -1,6 +1,6 @@ #!/bin/bash # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 -source "$(dirname "$0")/lib/ulib/ulib" || exit 1 +source "$(dirname -- "$0")/lib/ulib/ulib" || exit 1 urequire DEFAULTS woinst woinst "$@" diff --git a/woinst.sh b/woinst.sh new file mode 100755 index 0000000..796b995 --- /dev/null +++ b/woinst.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 +# Version de woinst qui fonctionne avec /bin/sh. Le contrôle est transmis à +# bash, qui est recherché dans une liste de répertoires standards +. `dirname -- "$0"`/lib/ulib/ulibsh || exit 1 +urequire DEFAULTS woinst + +woinst "$@"