gratifiant > linux.debian.user.french

hd (06/01/2009, 11h00)
Bonjour,

Je rencontre un problème avec l'expansion des variables sous bash

J'utilise un script (que je ne peux modifier car il fait partie d'un
package tiers) qui lance un ./configure en lui passant des paramamètres
additionnels via une variable MY_ARGS

le script est quelque chose comme :

#!/bin/sh
.....
../configure ${MY_ARGS}
....

et je le lance avec la commande :
MY_ARGS='--enable-truc CFLAGS="-g3 -O0"' ./script.sh

je m'attends à ce qu'il soit interprété comme :
./configure --enable-truc CFLAGS="-g3 -O0"

mais bash le transforme en :
./configure --enable-truc 'CFLAGS="-g3' '-O0"'
ce qui fait 3 paramètres pour "./configure" au lieu de 2
et évidemment ./configure sort en erreur en indiquant qu'il ne comprend
pas le paramètre -O0

Pourriez vous m'indiquer la bonne syntaxe pour que bash fasse ... ce que
je voudrais qu'il fasse

merci
Régis Grison (06/01/2009, 11h40)
hd a écrit :
> Bonjour,
> Je rencontre un problème avec l'expansion des variables sous bash
> [...]
> et je le lance avec la commande :
> MY_ARGS='--enable-truc CFLAGS="-g3 -O0"' ./script.sh
> je m'attends à ce qu'il soit interprété comme :
> ./configure --enable-truc CFLAGS="-g3 -O0"
> mais bash le transforme en :
> ./configure --enable-truc 'CFLAGS="-g3' '-O0"'
> [...]


Là comme ça, je serais tenté de complètement contourner le problème :
dans le shell :
export CFLAGS="-g3 -O0"

ensuite tu peux lancer ton script avec dans la variable MY_ARGS :
MY_ARGS="--enable-truc ./script.sh"

Sinon, un truc auquel on ne pense pas toujours c'est l'argument -- qui
permet de séparer les arguments d'un appli des arguments de l'appli
passée en paramètres. Mais je pense que la solution est au dessus.

Régis.
hd (06/01/2009, 12h00)
Régis Grison a écrit :
> hd a écrit :
> Là comme ça, je serais tenté de complètement contourner le problème :
> dans le shell :
> export CFLAGS="-g3 -O0"

oui mais le pb est que le "script.sh" bidouille lui-même le CFLAGS. Donc
mon CFLAGS déclaré en externe (via export) sera détruit entre temps
> ensuite tu peux lancer ton script avec dans la variable MY_ARGS :
> MY_ARGS="--enable-truc ./script.sh"

je suppose que tu voulais dire
MY_ARGS="--enable-truc" ./script.sh
> Sinon, un truc auquel on ne pense pas toujours c'est l'argument -- qui
> permet de séparer les arguments d'un appli des arguments de l'appli
> passée en paramètres. Mais je pense que la solution est au dessus.

il me semble avoir déjà vu ça avec 'startx'
startx 'client param' -- 'server param'
mais dans ce cas, c'est 'startx' qui gère le '--' (qui le parse)
le '--' n'a pas de signification particulière pour bash à ma connaissance
est ce de cela dont tu veux parler ou évoques tu autre chose ?
Romaric DEFAUX (06/01/2009, 12h30)
hd a écrit :
[..]
> Pourriez vous m'indiquer la bonne syntaxe pour que bash fasse ... ce
> que je voudrais qu'il fasse
> merci Bonjour,


As-tu déjà essayé de protégé les double quote par \ ?
MY_ARGS='--enable-truc CFLAGS=\"-g3 -O0\"' ./script.sh
Régis Grison (06/01/2009, 13h00)
hd a écrit :
> Régis Grison a écrit :
> oui mais le pb est que le "script.sh" bidouille lui-même le CFLAGS.
> Donc mon CFLAGS déclaré en externe (via export) sera détruit entre temps

Heu... si script.sh bidouille le CFLAGS, je ne suis pas sûr que le
passer comme tu veux le faire marche mieux, si ?

>> ensuite tu peux lancer ton script avec dans la variable MY_ARGS :
>> MY_ARGS="--enable-truc ./script.sh"

> je suppose que tu voulais dire
> MY_ARGS="--enable-truc" ./script.sh

Là je suis un peu paumé, si tu mets des "" juste autour d'un argument,
ne pas en mettre du tout ferait la même chose, non ?

> il me semble avoir déjà vu ça avec 'startx'
> startx 'client param' -- 'server param'
> mais dans ce cas, c'est 'startx' qui gère le '--' (qui le parse)
> le '--' n'a pas de signification particulière pour bash à ma connaissance
> est ce de cela dont tu veux parler ou évoques tu autre chose ?

Je veux bien parler de ça mais il me semble que c'est géré au niveau du
shell :
rg@merlin:~$ echo -n test
testrg@merlin:~$ echo -- -n test
-- -n test
rg@merlin:~$

Ceci dit, je ne penses toujours pas que ça soit la solution. La
proposition de Romaric DEFAUX de mettre des \" me semble beaucoup plus
intéressante.

Régis.
hd (06/01/2009, 13h10)
Romaric DEFAUX a écrit :
> hd a écrit :
> Bonjour,
> As-tu déjà essayé de protégé les double quote par \ ?
> MY_ARGS='--enable-truc CFLAGS=\"-g3 -O0\"' ./script.sh

ben oui ... et dans ce cas il le protège tellement que le '\' est aussi
passé en param
MY_ARGS='--enable-truc CFLAGS=\"-g3 -O0\"' ./script.sh
se transforme en
./configure --enable-truc 'CFLAGS=\"-g3' '-O0\"'

donc ce n'est pas bon ...
hd (06/01/2009, 14h00)
[...]

> Heu... si script.sh bidouille le CFLAGS, je ne suis pas sûr que le
> passer comme tu veux le faire marche mieux, si ?

dans le cript, il y a
....
CFLAGS=
../configure ${MY_ARGS}
....

donc le CFLAGS défini via MY_ARGS est protégé (il "passe par dessus" en
quelque sorte)
>>> ensuite tu peux lancer ton script avec dans la variable MY_ARGS :
>>> MY_ARGS="--enable-truc ./script.sh"

>> je suppose que tu voulais dire
>> MY_ARGS="--enable-truc" ./script.sh

> Là je suis un peu paumé, si tu mets des "" juste autour d'un argument,
> ne pas en mettre du tout ferait la même chose, non ?

si mais ce n'est pas ce que tu avais écrit, c'est pour cela que je
posais la question

[...]

> Je veux bien parler de ça mais il me semble que c'est géré au niveau
> du shell :
> rg@merlin:~$ echo -n test
> testrg@merlin:~$ echo -- -n test
> -- -n test
> rg@merlin:~$

effectivement en relisant le 'man bash', l'option '--' est géré
directement par bash, je ne l'avais pas compris
ceci dit j'ai essayé (sans trop comprendre)
MY_ARGS='--enable-truc -- CFLAGS=-g3 -O0' ./script.sh
et
MY_ARGS='--enable-truc -- "CFLAGS=-g3 -O0"' ./script.sh
sans succès, bash considère -O0 toujours que c'est un paramètre indépendant
Romaric DEFAUX (06/01/2009, 14h00)
hd a écrit :
> Romaric DEFAUX a écrit :
> ben oui ... et dans ce cas il le protège tellement que le '\' est
> aussi passé en param
> MY_ARGS='--enable-truc CFLAGS=\"-g3 -O0\"' ./script.sh
> se transforme en
> ./configure --enable-truc 'CFLAGS=\"-g3' '-O0\"'
> donc ce n'est pas bon ...

J'ai l'impression que c'est l'espace entre -g3 et -00 qui pose problème.
Il considèrerait que MY_ARGS contient une suite d'arguments séparés par
des espaces. Et si tu protèges l'espace ça fait quoi ?
Tu pourrais nous montrer les parties de script.sh qui traite MY_ARGS et
CFLAGS ? Il y a peut-être un bug...
Guy Roussin (06/01/2009, 15h10)
> Pourriez vous m'indiquer la bonne syntaxe pour que bash fasse ... ce
> que je voudrais qu'il fasse et


MY_ARGS="--enable-truc CFLAGS=\"-g3 -O0\"" ./script.sh

ça le fait ?
hd (06/01/2009, 15h20)
Guy Roussin a écrit :
>> Pourriez vous m'indiquer la bonne syntaxe pour que bash fasse ... ce
>> que je voudrais qu'il fasse

> et
> MY_ARGS="--enable-truc CFLAGS=\"-g3 -O0\"" ./script.sh
> ça le fait ?

ben non, bash me transforme cela en
./configure --enable-truc 'CFLAGS="-g3' '-O0"'
hd (06/01/2009, 16h00)
Romaric DEFAUX a écrit :
[...]

> J'ai l'impression que c'est l'espace entre -g3 et -00 qui pose
> problème. Il considèrerait que MY_ARGS contient une suite d'arguments
> séparés par des espaces. Et si tu protèges l'espace ça fait quoi ?
> Tu pourrais nous montrer les parties de script.sh qui traite MY_ARGS
> et CFLAGS ? Il y a peut-être un bug...

ce script permet normalement de lancer les outils autotools puis le
"configure" avec des options prédéfinis (path pour les bins, libs ...)
il utilise une variable MY_ARGS qui permet de surcharger les options de
'l'extérieur' du script sans avoir à le modifier
dans mon cas, je veux compiler en debug et donc ajouter les options
'--enable-debug CFLAGS="-g3 -O0"'
si je suis obliger de modifier le script pour cela, la variable MY_VARS
ne sert plus à rien ...
voici un raccourci du script

$ cat script.sh
#!/bin/sh

mylog() {
echo "${@}"
"${@}"
return $?
}

myconf() {
# ...
# differentes chose comme autoreconf ...
# ...
mylog "./configure" "${@}" ${MY_ARGS}
# ...
}
myconf --sbindir=/usr/sbin

et voici une trace :

$ MY_ARGS='--enable-debug CFLAGS="-g3 -O0"' bash -xv script.sh
#!/bin/sh

mylog() {
echo "${@}"
"${@}"
return $?
}

myconf() {
# ...
# différentes chose comme autoreconf ...
# ...
mylog "./configure" "${@}" ${MY_ARGS}
# ...
}

myconf --sbindir=/usr/sbin
+ myconf --sbindir=/usr/sbin
+ mylog ./configure --sbindir=/usr/sbin --enable-debug 'CFLAGS="-g3' '-O0"'
+ echo ./configure --sbindir=/usr/sbin --enable-debug 'CFLAGS="-g3' '-O0"'
../configure --sbindir=/usr/sbin --enable-debug CFLAGS="-g3 -O0"
+ ./configure --sbindir=/usr/sbin --enable-debug 'CFLAGS="-g3' '-O0"'
configure: error: unrecognized option: -O0"

Visiblement, l'espace entre -g3 et -O0 pose problème

Je vais me replonger dans la doc de bash ...
Jacques L'helgoualc'h (06/01/2009, 20h10)
hd a écrit, mardi 6 janvier 2009, à 14:51 :
> [...]


Bonjour,

> $ MY_ARGS='--enable-debug CFLAGS="-g3 -O0"' bash -xv script.sh
> #!/bin/sh


Plutôt « sh -xv », non ? Ton problème tient sans doute à l'ordre suivant
lequel le shell effectue ses évaluations --- tu pourrais demander sur
news:unix

Pour contourner le problème, essaie

sh -vx <(sed -e '/\${MY_ARGS}/ s//--enable-truc CFLAGS="-g3 -O0"/g' script.sh)

?
pmenier (07/01/2009, 11h30)
hd a écrit :
> Guy Roussin a écrit :
> ben non, bash me transforme cela en
> ./configure --enable-truc 'CFLAGS="-g3' '-O0"' Salut


Et si tu mets la valeur de MY_ARGS dans un fichier puis:

../configure $(cat le_fichier)

Pat
Thomas Preud'homme (07/01/2009, 16h40)
The Tuesday 06 January 2009 09:57:41 hd, you wrote :
[..]
> ...
> et je le lance avec la commande :
> MY_ARGS='--enable-truc CFLAGS="-g3 -O0"' ./script.sh


En fait les ' sont retirer par le shell au moment de l'évaluation de la ligne.

Au final il mettra dans MY_ARGS : --enable-truc CFLAGS="-g3 -O0" ./script.sh

Ensuite quand tu appelles configure avec $MY_ARGS la variable est remplacée
par sa signification (Cf ligne du dessus) et le découpage est fait suivant
les espaces sauf pour les variables qui étaient entre quites.

Cf man bash : Expansion is performed on the command line after it has
been split into words. There are seven kinds of expansion performed: brace
expansion, tilde expansion, parameter and variable expansion, command
substitution, arithmetic expansion, word splitting, and pathname expansion.

Puis plus loin :

The shell scans the results of parameter expansion, command substitution, and
arithmetic expansion that did not occur within double quotes for word
splitting.

Autrement dit les quotes ne sont interprétés que dans la ligne de commande,
pas dans les variables. Toute quote dans une variable est considérée comme un
caractère (c'est comme si la quote avait été échappée par le shell).

Si tu veux obtenir le résultat espéré tu vas devoir faire un eval :

val [arg ...]
The args are read and concatenated together into a single
command. This command is then read and executed by the shell, and its exit
status is returned as the value of eval. If there are no args, or only
null arguments, eval returns 0.

Ce qui dans ton cas donne :

MY_ARGS='--enable-truc CFLAGS="-g3 -O0"' ./script.sh

puis

eval ./configure ${MY_ARGS}

> je m'attends à ce qu'il soit interprété comme :
> ./configure --enable-truc CFLAGS="-g3 -O0"
> mais bash le transforme en :
> ./configure --enable-truc 'CFLAGS="-g3' '-O0"'
> ce qui fait 3 paramètres pour "./configure" au lieu de 2
> et évidemment ./configure sort en erreur en indiquant qu'il ne comprend
> pas le paramètre -O0
> Pourriez vous m'indiquer la bonne syntaxe pour que bash fasse ... ce que
> je voudrais qu'il fasse
> merci


Cordialement,

Thomas Preud'homme
hd (07/01/2009, 18h30)
[...]
> Si tu veux obtenir le résultat espéré tu vas devoir faire un eval :
> val [arg ...]
> The args are read and concatenated together into a single
> command. This command is then read and executed by the shell, and its exit
> status is returned as the value of eval. If there are no args, or only
> null arguments, eval returns 0.
> Ce qui dans ton cas donne :
> MY_ARGS='--enable-truc CFLAGS="-g3 -O0"' ./script.sh
> puis
> eval ./configure ${MY_ARGS}

merci pour toutes ces explications.
mais comme rien n'est simple, le script.sh en question ne dépend pas de
moi (fait par un tiers), je ne peux donc pas le modifier directement.
avec toutes les réponses à ce fil, j'en déduis qu'il n'y a pas de
solution en ne jouant que sur la définition de la variable.
donc je vais demander des modif ... dans script.sh

merci pour tout

Discussions similaires