[bash encore] vérifier existence d'arguments optionels vides

Fermé
Swiss Knight Messages postés 1956 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 27 juillet 2016 - 6 mai 2013 à 16:18
Swiss Knight Messages postés 1956 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 27 juillet 2016 - 6 mai 2013 à 21:50
Salut,

Encore une question sur le bash... pour changer :S
Je me familiarise peu à peu avec getopts mais c'est tordu pour moi encore...

J'aimerai vérifier si pour une option non obligatoire, un argument a été passé ou non.
Et si c'est "non" mais que l'option a été activée, assigner à une variable une valeur par défaut.
Et si l'option n'a pas été activée, ne rien assigner du tout à cette variable.

(je me mélange sans doute les pinceaux, mais j'appelle ici option les lettres passées au script après un tiret, et paramètres, les chaînes de caractères qui peuvent suivre ces lettres)


Exemple :
while getopts ":d: :c:" option; do
    case "${option}"
    in
        d) fichier="${OPTARG}";;
        c) var1="${OPTARG}";;
etc...
    esac
done


Ensuite, j'assigne à var1 une valeur par défaut si elle n'existe pas (mais que l'option -c est activée) :

if [ ! "${var1}" ]; then
    var1="chainedecaractères"
fi


Sauf qu'avec ça, lorsque je NE passe PAS l'option -c au script, il assigne quand même "chainedecaractères" à la variable var1.
Or si cette option -c n'est pas présente, la variable var1 NE doit PAS exister, tout simplement.
Et si -c a été passée avec son paramètre, par exemple : -c "monrépertoire", il faut que var1 contienne "monrépertoire".

J'ai essayé de mettre le test if sous le case c) mais sans succès...
Pour le moment, quand je lance mon script sans l'option -c, il assigne à var1 la chaîne par défaut et tout le fonctionnement s'en trouve modifié.


Merci beaucoup de vos éclairages !
A voir également:

4 réponses

zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 423
6 mai 2013 à 17:00
Salut,

Voir man bash, le remplacement des paramètres.

Exemple :

$ cat foo.sh 
#! /bin/bash

while getopts ":d: :c:" option; do
    case "${option}"
    in
        d) fichier="${OPTARG}";;
        c) var1="${OPTARG:+${OPTARG}}";;
    esac
done

echo "Fichier = ${fichier}"
echo "var1 = ${var1}"



$ ./foo.sh -d plop -c PARAMÉTRE   # Option définie avec argument
Fichier = plop
var1 = PARAMÉTRE

$ ./foo.sh -d plop   # Option non définie 
Fichier = plop
var1 = 

$ ./foo.sh -d plop -c   # Option définie sans argument
Fichier = plop
var1 = 

$ 

0
Swiss Knight Messages postés 1956 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 27 juillet 2016 110
6 mai 2013 à 18:06
Salut et merci pour ta réponse zipe, mais je n'y arrive pas...

Il faudrait théoriquement dans ton dernier cas, que var1="valeur_par_défaut"
or en mettant ceci par ex. sous l'option c) var1="${OPTARG:=valeur_par_défaut}";;

Et en passant juste l'option -c sans paramètre, il a envie de lire la prochaine option comme étant le paramètre de -c !

J'ai essayé avec :
${OPTARG:+valeur_par_défaut}";;
${OPTARG:-valeur_par_défaut}";;
${OPTARG:=valeur_par_défaut}";;

Aucun ne donne ce que je cherche.
0
Swiss Knight Messages postés 1956 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 27 juillet 2016 110
6 mai 2013 à 18:48
Re-salut,

j'ai trouvé un élément de réponse ici :
https://www.unix.com/shell-programming-and-scripting/174768-using-default-value-getopts-case.html

apparemment getopt ne supporte pas les valeurs "par défaut".
On peut lui dire -c "" pour lui assigner "rien" et ainsi var1 prendra la valeur par défaut, c'est le seul bidouillage possible.

Mais si on souhaite se passer de devoir écrire deux doubles guillemets, il n'y apparemment pas de solution...
Une autre idée pour contourner ça est de définir var1 avant de parser les arguments.
Si l'option c existe mais est vide, var1 garde la valeur par défaut qu'on lui aura assignée avant. Sinon il prendra celle en paramètre à l'option c.

Par contre, c'est le serpent qui se mord la queue cette histoire ; parce que si je n'active pas l'option c, var1 a quand même la valeur par défaut avec cette bidouille.
Or je cherche absolument à ce que var1 n'existe même pas si c n'est pas donnée au script !

:(
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 423
6 mai 2013 à 19:25
S'il y a d'autres options derrière "-c", peut être devrais-tu essayer de mettre cette option en dernier dans la liste, comme ça tu pourrais la traiter sans arguments, non ?
0
Swiss Knight Messages postés 1956 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 27 juillet 2016 110
6 mai 2013 à 20:29
...pour ensuite poser un
if [[ $* =~ .*-c.* ]]; then
var1="valeur_par_default"
fi

j'y pense... mais ça risque de poser plus de "petits soucis" qu'autre chose.
Mettre la valeur assignée à var1 en dur dans le fichier en poserait moins dans le cas présent.


Je trouve dommage qu'on ne puisse pas avoir des arguments optionnels avec getopts, ce serait vraiment utile.
M'enfin c'est comme ça.

Merci quand même ; j'apprends beaucoup en essayant des trucs.
0
Swiss Knight Messages postés 1956 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 27 juillet 2016 110
6 mai 2013 à 21:50
Tiens je suis tombé sur ça :

"-o, --options shortopts
The short (one-character) options to be recognized. If this option is not found, the first parameter of getopt that does not start with a '-' (and is not an option argument) is used as the short options string. Each short option character in shortopts may be followed by one colon to indicate it has a required argument, and by two colons to indicate it has an optional argument. The first character of shortopts may be '+' or '-' to influence the way options are parsed and output is generated (see section SCANNING MODES for details). "
https://linux.die.net/man/1/getopt

apparemment on peut utiliser deux ":" pour dire qu'un argument est optionnel, mais même avec :c:: dans la liste des options je n'arrive à rien :
#! /bin/bash

while getopts ":d: :c:: :e" option; do
    case "${option}"
    in
        d) fichier="${OPTARG}";;
        c) var1="${OPTARG}";;
        e) var3="Bonjour";;
    esac
done

echo "Fichier=${fichier}"
echo "variable_1=$var1"
echo "variable_3=$var3"

donne :
$ ./foo.sh -d plop -c -e
Fichier=plop
variable_1=-e
variable_3=


idem en remplaçant la ligne du c) par :
c) var1="${OPTARG:-default_value}";;

ou
c) var1="${OPTARG:=default_value}";;


Et avec un signe "+" :
#! /bin/bash

while getopts ":d: :c:: :e" option; do
    case "${option}"
    in
        d) fichier="${OPTARG}";;
        c) var1="${OPTARG:+default_value}";;
        e) var3="Bonjour";;
    esac
done

echo "Fichier=${fichier}"
echo "variable_1=$var1"
echo "variable_3=$var3"

ça donne un truc légèrement différent :
$ ./foo.sh -d plop -c -e
Fichier=plop
variable_1=default_value
variable_3=

le -e tombe dans l'oubli... (??!)


0