En script shell, quelle est la différence entre ces deux instructions lors de l'assignation d'une variable à une autre :
a=$b
et
a="$b"
et quand devrais-je utiliser l'une plutôt que l'autre ?
En script shell, quelle est la différence entre ces deux instructions lors de l'assignation d'une variable à une autre :
a=$b
et
a="$b"
et quand devrais-je utiliser l'une plutôt que l'autre ?
Je ne pense pas qu'il y ait de grande différence ici. Oui, il est conseillé d'encadrer une variable entre guillemets doubles lorsque cette variable est référencée. Cependant, $x
ne semble pas être référencé ici dans votre question.
y=$x
n'a pas en soi d'impact sur la façon dont les espaces blancs seront gérés. Ce n'est que lorsque $y
est effectivement utilisé que les guillemets ont de l'importance. Par exemple :
$ x=" a b "
$ y=$x
$ echo $y
a b
$ echo "$y"
a b
De la section 2.9.1 de la spécification de syntaxe de shell POSIX:
Chaque assignation de variable doit être développée pour l'expansion tilde, l'expansion de paramètre, la substitution de commande, l'expansion arithmétique et la suppression des guillemets avant d'attribuer la valeur.
La découpe de chaînes et le globbing (les étapes que les guillemets doubles suppriment) ne sont pas dans cette liste, et les autres ne sont pas pertinents pendant l'expansion de variable (par exemple, l'expansion de tilde nécessite un tilde dans le code source en cours d'analyse, pas dans le contenu d'une variable).
Ainsi, les guillemets sont superflus dans toutes les affectations simples (je ne parle pas ici de celles mises en œuvre avec des arguments à des commandes telles que déclarer
, export
ou des commandes similaires) sauf celles où (1) le comportement de chaînes entre guillemets simples, pas guillemets doubles, est souhaité; ou (2) l'espacement ou tout autre contenu dans la valeur serait autrement analysé comme syntaxique plutôt que littéral.
(Notez que la décision sur la façon d'analyser une commande - donc, qu'il s'agisse ou non d'une affectation, d'une commande simple, d'une commande composée, ou autre -- a lieu <em>avant</em> les expansions de paramètres; ainsi, <code>var=$1</code> est déterminé comme une affectation avant que la valeur de <code>$1</code> ne soit même considérée! Si cela n'était pas vrai, de telle sorte que des données pourraient devenir silencieusement syntaxiques, il serait bien plus difficile - voire impossible - d'écrire un code sécurisé manipulant des données non fiables en bash).
Il n'y a pas de bonnes raisons de mettre des guillemets autour du côté droit d'une attribution de variable lorsqu'il est utilisé comme une instruction à lui seul.
Le côté droit d'une instruction d'attribution n'est pas soumis à la division des mots (ou à l'expansion des accolades), etc. donc n'a pas besoin de guillemets pour être attribué correctement. Toutes les autres expansions (pour autant que je sache) se produisent sur le côté droit mais se produisent également entre guillemets doubles donc les guillemets ne servent à rien.
Cela étant dit, il y a des raisons de ne pas mettre de guillemets autour du côté droit. Notamment comment résoudre l'erreur "bash: !d': event not found" dans la substitution de commandes Bash (voir spécifiquement ma réponse et la réponse de rici).
Voici quelques autres exemples: (ayant deux fichiers dans le répertoire actuel t.sh
et file
)
a='$(ls)' # pas de substitution de commande
b="$(ls)" # substitution de commande, pas de découpe de mot
c='*' # pas d'expansion de nom de fichier
d="*" # pas d'expansion de nom de fichier
e=* # pas d'expansion de nom de fichier
f=$a # pas d'expansions ou de découpes
g="$a" # pas d'expansions ou de découpes
h=$d # pas d'expansions ou de découpes
echo ---'$a'---
echo $a # pas de substitution de commande
echo ---'$b'---
echo $b # découpage de mot
echo ---'"$b"'---
echo "$b" # pas de découpage de mot
echo ---'$c'---
echo $c # expansion de nom de fichier, découpage de mot
echo ---'"$c"'---
echo "$c" # pas d'expansion de nom de fichier, pas de découpage de mot
echo ---'$d'---
echo $d # expansion de nom de fichier, découpage de mot
echo ---'"$d"'---
echo "$d" # pas d'expansion de nom de fichier, pas de découpage de mot
echo ---'"$e"'---
echo "$e" # pas d'expansion de nom de fichier, pas de découpage de mot
echo ---'$e'---
echo $e # expansion de nom de fichier, découpage de mot
echo ---'"$f"'---
echo "$f" # pas d'expansion de nom de fichier, pas de découpage de mot
echo ---'"$g"'---
echo "$g" # pas d'expansion de nom de fichier, pas de découpage de mot
echo ---'$h'---
echo $h # expansion de nom de fichier, découpage de mot
echo ---'"$h"'---
echo "$h" # pas d'expansion de nom de fichier, pas de découpage de mot
Sortie:
---$a---
$(ls)
---$b---
file t.sh
---"$b"---
file
t.sh
---$c---
file t.sh
---"$c"---
*
---$d---
file t.sh
---"$d"---
*
---"$e"---
*
---$e---
file t.sh
---"$f"---
$(ls)
---"$g"---
$(ls)
---$h---
file t.sh
---"$h"---
*
Une chose intéressante à remarquer est que la substitution de commande se produit dans les affectations de variables si elles sont entre guillemets, et si le RHD est donné explicitement comme "$(ls)"
et non implicitement comme "$a"
.
Guide avancé sur le script Bash : Chapitre 5 : Quoting
Lorsque vous faites référence à une variable, il est généralement conseillé d'encadrer son nom entre guillemets. Cela empêche la réinterprétation de tous les caractères spéciaux dans la chaîne entre guillemets. Utilisez des guillemets doubles pour éviter la division des mots. Un argument encadré de guillemets doubles se présente comme un seul mot, même s'il contient des séparateurs d'espaces.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.