doubles quotes dans une option

Christophe Martin Christophe.Martin at univ-brest.fr
Thu Jan 17 14:56:39 CET 2013


Bonjour, et bonne année 2013

Le 17 janv. 2013 à 14:07, Daniel Caillibaud a écrit :

> Bonjour,
> 
> Il reste du monde par ici ?
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



More information about the Shell mailing list