doubles quotes dans une option
Bonjour, Il reste du monde par ici ? Une question bête sur laquelle je sèche : comment mettre des doubles quotes dans une variable bash qui va servir comme option d'une autre commande ? Un exemple simple pour illustrer bash OPT="--format=\"commas\"" echo $OPT --format="commas" ls $OPT # ls: invalid argument `"commas"' for `--format' pas mieux avec OPT="--format=\\"commas\\"" ou OPT="--format='commas'" ou cmd="ls $OPT" $cmd $($cmd) `$cmd` (évidemment les quotes ne sont pas obligatoires dans cet exemple trivial, mais dans mon exemple réel j'ai une chaîne avec espace, mettre des "\ " pour éviter les " règle pas le pb) -- Daniel Il est parfaitement monstrueux de s'apercevoir que les gens disent dans notre dos des choses qui sont absolument et entièrement vraies. Oscar Wilde
Bonjour,
Il reste du monde par ici ?
Une question bête sur laquelle je sèche : comment mettre des doubles quotes dans une variable bash qui va servir comme option d'une autre commande ?
Un exemple simple pour illustrer
bash OPT="--format=\"commas\"" echo $OPT --format="commas" ls $OPT # ls: invalid argument `"commas"' for `--format'
pas mieux avec OPT="--format=\\"commas\\"" ou OPT="--format='commas'" ou cmd="ls $OPT" $cmd $($cmd) `$cmd`
(évidemment les quotes ne sont pas obligatoires dans cet exemple trivial, mais dans mon exemple réel j'ai une chaîne avec espace, mettre des "\ " pour éviter les " règle pas le pb)
et sans mettre de quote pour la variable ? $ OPT=--format="commas" $ ls $OPTS bar, foo Yoann
Bonjour, On 2013-01-17 14:07:30 +0100, Daniel Caillibaud wrote:
Une question bête sur laquelle je sèche : comment mettre des doubles quotes dans une variable bash qui va servir comme option d'une autre commande ?
Un exemple simple pour illustrer
bash OPT="--format=\"commas\"" echo $OPT --format="commas"
Voilà, comme cela. Mais le problème, c'est qu'en général...
ls $OPT # ls: invalid argument `"commas"' for `--format'
Il ne faut *pas* de quotes: --format=commas Car le but des quotes est d'être interprétés par le shell, pas à être passés dans l'argument. En particulier, les quotes servent à "protéger" les espaces, pour qu'ils soient considérés comme faisant partie de l'argument et non pas séparer deux arguments. Je pense que ton problème est maintenant: comment différencier les espaces séparant les options des espaces faisant partie d'une valeur d'une option. Soit c'est prévu par l'utilitaire qui va lire la variable d'environnement (voir au cas par cas), soit si tu passes toi-même la variable dans un script, il faut un système pour la réévaluer par le shell (dans ce cas, les quotes sont utiles): c'est le but de l'utilitaire eval.
pas mieux avec OPT="--format=\\"commas\\"" ou OPT="--format='commas'" ou cmd="ls $OPT" $cmd $($cmd) `$cmd`
eval ls $OPT -- Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
On 2013-01-17 14:35:54 +0100, Vincent Lefevre wrote:
eval ls $OPT
En fait, plutôt: eval ls "$OPT" au cas où il y aurait des espaces doubles. Un exemple: $ OPT="-l --time-style='+%Y-%m-%d %H:%M:%S'" (Les 2 espaces dans la chaîne du --time-style sont voulus.) $ eval ls "$OPT" Sans les guillemets, $OPT est sujet au "word splitting", donc toute succession d'espaces dans la chaîne va être remplacée par un seul espace dans la chaîne produite par eval pour le shell. -- Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
Bonjour,
Il reste du monde par ici ?
Bonjour, et bonne année 2013 Le 17 janv. 2013 à 14:07, Daniel Caillibaud a écrit : peut-être un peu...
Une question bête sur laquelle je sèche : comment mettre des doubles quotes dans une variable bash qui va servir comme option d'une autre commande ?
Un exemple simple pour illustrer
bash OPT="--format=\"commas\"" echo $OPT --format="commas" ls $OPT # ls: invalid argument `"commas"' for `--format' C'est bien, mais il manque le eval
pas mieux avec OPT="--format=\\"commas\\"" C'est pas bien : tu obtiens «--format=\» concaténé avec «commas» concaténé avec «\» concaténé avec une chaine vide «» ou OPT="--format='commas'" c'est bien mais il manque le eval ou cmd="ls $OPT" $cmd C'est pas bien, mais presque. Le redécoupage va se faire au milieu de la chaine «commas» si elle contenait des espaces
$($cmd) pas bien non plus. Si la précédente n'est pas valide, interprété le résultat de la précédente comme un nouvelle commande ne peut que mener, dans le meilleur des cas à rien du tout, dans le pire des cas à la catastrophe. `$cmd` ça n'est pas mieux. c'est pareil.
(évidemment les quotes ne sont pas obligatoires dans cet exemple trivial, mais dans mon exemple réel j'ai une chaîne avec espace, mettre des "\ " pour éviter les " règle pas le pb)
.... va servir pour une autre commande ... => utiliser "eval" Mais alors, attention, il faut effectivement bien quoter les arguments... Simplement rajouter des guillemet peut s'avérer dangereux si tu ne contrôle pas exactement ce qui est entouré de guillemets : Imagine ce qui se passerai si, au lieu de la chaine «format«, tu as une chaine dans une variable et que cette chaine, pour une raison quelconque contient des guillemets, ou des ` ou des $ ou d'autre machins dangeureux. Le mieux pour quoter est de demander à bash de le faire. Il sait bien mieux que tous les autres s'il faut mettre ou non des quillemets, des \ ou autres bizareries. printf %q "$variable" quote son argument correctement quelque soit le contenu initial de ce qu'on veut quoter. (toujours mettre des quillemets autour de la variable) exemple : a='Joli format' OPT="$( printf %q "--format=$a")" echo "macommande $OPT" ça doit afficher un truc du genre macommande --format=Joli\ format ce qu'on peut parfaitement et sereinement donner à éval. tu peux donc utiliser eval "macommande $OPT" On peut faire totalement confiance à cette technique. Même si le contenu de la variable a est bizarre. exemple a='joli format "; rm -rf /' OPT="$( printf %q "--format=$a")" echo "macommande $OPT" ça affiche ceci : macommande --format=joli\ format\ \"\;\ rm\ -rf\ / ce qui est parfaitememnt quoté et utilisable dans un eval Une dernière chose. J'utilise, juste pour vérifier, la commande args en lieu et place de macommande, histoire de vérifier qu'on ne fait pas de bêtise script args -------------------- #! /bin/sh echo args a recu $# parametres j=1 for i do printf '%3d -->%s<--\n' "$j" "$i" j=$(( $j + 1 )) done -------------------- avec l'exemple précédent, eval "args $OPT" produit ceci: args recu 1 arguments 1 -->--format=joli format "; rm -rf /<-- /CM -- Christophe Martin, Administrateur système CNRS/UBO/UMR6538/IUEM, rue Dumont d'Urville tél : (33) 2 98 49 87 13 29280 PLOUZANÉ fax : (33) 2 98 49 87 60
On 2013-01-17 14:56:39 +0100, Christophe Martin wrote:
script args -------------------- #! /bin/sh echo args a recu $# parametres j=1 for i do printf '%3d -->%s<--\n' "$j" "$i" j=$(( $j + 1 )) done --------------------
Tiens, j'ai une commande similaire, sauf que j'écris dans un fichier, que je peux relire avec emacs. Si on affiche directement dans un terminal, il faudrait se préoccuper des caractères non affichables, e.g. args "$(printf "abc\bde")" -- Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
Le 17/01/13 à 14:07, Daniel Caillibaud <ml@lairdutemps.org> a écrit : DC> Il reste du monde par ici ? Je sais pas si y'en a beaucoup mais c'est d'une efficacité redoutable ! Merci à tous, j'ai appris des choses intéressantes :-) Finalement j'ai retenu pour mon utilisation IONICE="ionice -c 2 -n 7 nice" RSYNC_OPTS="--rsync-path=\"$IONICE rsync\"" ... eval $IONICE rync $RSYNC_OPTS autres options ... -- Daniel La preuve irréfutable qu'il existe de l'intelligence sur les autres planètes c'est qu'ils n'ont JAMAIS cherché a entrer en contact avec nous. Première page d'un "Calvin et Hobbes"
On 2013-01-17 16:09:52 +0100, Daniel Caillibaud wrote:
Finalement j'ai retenu pour mon utilisation
IONICE="ionice -c 2 -n 7 nice" RSYNC_OPTS="--rsync-path=\"$IONICE rsync\"" ... eval $IONICE rync $RSYNC_OPTS autres options ...
Habituellement je préfère utiliser zsh, qui ne fait pas de word splitting par défaut. Mais pour que ça marche, cela impose d'utiliser des variables shell et non des variables d'environnement (si c'était nécessaire), car on a besoin de tableaux. Par exemple: IONICE="ionice -c 2 -n 7 nice" rsync_opts=(--rsync-path="$IONICE rsync") ... ${=IONICE} rync $rsync_opts ou bien: ionice=(ionice -c 2 -n 7 nice) rsync_opts=(--rsync-path="$ionice rsync") ... $ionice rync $rsync_opts -- Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
participants (4)
-
Christophe Martin
-
Daniel Caillibaud
-
informatique@mistur.org
-
Vincent Lefevre