(1 réponse)
Fermé il y a 4 ans.
J'ai tendance à citer les substitutions de commandes comme indiqué ci-dessous, même lors de l'affectation de leur sortie à une variable :
var="$(command)"
Est-ce vraiment nécessaire cependant? Quand est-ce que ça casse ? La réponse acceptée ici prétend :
DIRNAME=”$(dirname $FILE)” ne fera pas ce que vous voulez si $FILE contient des espaces blancs ou des caractères globaux [?*.
Le lien pointe vers l'excellente page de Grey Cat Wiki sur les citations, mais cette page ne mentionne pas spécifiquement la citation des substitutions de commandes. Et en citant la variable est clairement nécessaire, citer la substitution de commande elle-même ne semble pas l'être.
Cependant, le même article se termine par :
DIRNAME="$(dirname "$FILE")" est la méthode recommandée. Vous pouvez remplacer DIRNAME=par une commande et un espace sans rien changer d'autre, et dirname reçoit la chaîne correcte.
C'est ce que j'ai toujours pensé aussi et j'ai souvent écrit ici des articles qui ne le citaient pas. Cependant, la page wiki liée ci-dessus affirme également que :
Il existe quelques cas où les guillemets doubles peuvent être omis en toute sécurité :
Sur le côté droit d'une affectation simple. Vous pouvez écrire foo=$bar sans guillemets. Ceci est conforme à POSIX.
[. . . ]
Tant que var=$(command)
n'est pas vraiment une mission "simple", je n'ai cependant pas trouvé de cas où les devis étaient réellement nécessaires :
$ var=$(echo "foo bar baz") ## whitespace works
$ echo "$var"
foo bar baz
$ var=$(printf "foonbar * baz") ## so do globbing characters
$ echo "$var"
foo
bar * baz
$ var1="foonbar * baz"
$ var=$(printf "$var1") ## printing a variable doesn't make any difference
$ echo "$var"
foo
bar * baz
$ var=$(printf '%sn' "$var1")
$ echo "$var"
foonbar * baz
$ var=$(printf -- '-e %sn' "$var1") ## strings starting with - also work
$ echo "$var"
-e foonbar * baz
Bien sûr, les guillemets sont absolument nécessaires si la substitution de commande est utilisée directement pour des choses comme command1 "$(command2)"
, mais cela ne semble pas être le cas lors de l'affectation à une variable.
Alors, qu'est-ce que je rate ? Les devis sont-ils toujours nécessaires ? Quel cas particulier citera une substitution de commande lors de l'affectation de sa valeur de retour à une variable vous protéger ? Ou est-il toujours acceptable de ne pas citer une substitution de commande s'il s'agit du côté droit d'une opération d'affectation de variable ?
Réponse acceptée :
Comme référence, le manuel de Bash est clair à ce sujet :
Une variable peut être affectée par une instruction de la forme
name=[value]
Si la valeur n'est pas donnée, la variable reçoit la chaîne nulle. Toutes les valeurs subissent un développement de tilde, un développement de paramètres et de variables, une substitution de commande, un développement arithmétique et une suppression des guillemets (détaillé ci-dessous). […] Le fractionnement de mots n'est pas effectué , à l'exception de "[email protected]", comme expliqué ci-dessous. L'expansion du nom de fichier n'est pas effectuée.
Pas de division de mots, pas d'extension de nom de fichier, donc pas besoin de guillemets.
En relation:Outil de ligne de commande PostgreSQL psql et SET CONSTRAINTS DEFERRED?Comme pour POSIX, section 2.9.1 Commandes simples :
2. Les mots qui ne sont pas des affectations variables ou des renvois doivent être développés. S'il reste des champs après leur développement S'il reste des champs après leur développement, le premier champ doit être considéré comme le nom de la commande et les champs restants sont les arguments de la commande.
[…]
4. Chaque affectation de variable doit être étendu pour l'expansion du tilde, l'expansion des paramètres, la substitution de commande, l'expansion arithmétique et la suppression des guillemets avant d'attribuer la valeur.
Je ne sais pas si cela est censé être interprété comme signifiant que la division des champs ne se produit que pour les extensions effectuées à l'étape 2 ? L'étape 4 ne le fait pas mentionner le fractionnement des champs, bien que la section sur le fractionnement des champs ne mentionne pas non plus les affectations de variables comme exception à la production de plusieurs champs.