Dans un script shell, si je définis une variable telle que FOO=25
, y a-t-il une différence entre le référencer comme $FOO$
et ${FOO}$
?
Dans un script shell, si je définis une variable telle que FOO=25
, y a-t-il une différence entre le référencer comme $FOO$
et ${FOO}$
?
Réponses:
Dans la plupart des situations à la fois $var
et ${var}
sont les mêmes. (Notez que vous ne devez pas utiliser un $
à la fin!)
Un exemple où vous avez besoin d'accolades est lorsque vous devez placer une variable dans une chaîne continue.
Exemple:
var=hel
echo ${var}lo
sortira hello
.
Pour répondre à votre question principale, ${foo}
est appelé "expansion des paramètres" . Pour être précis, le $
paramètre lui - même démarre l'expansion des paramètres, ils { }
sont en fait facultatifs selon la spécification POSIX , mais peuvent être utiles pour indiquer la fin du nom de la variable:
$ foo="bar"
$ echo $fooBaz ## fails, no variable named $fooBaz exists
$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz
Fondamentalement, $foo
et ${foo}
sont identiques. Hormis les cas comme ci-dessus ou lorsque vous faites de la manipulation de chaînes , ils sont complètement équivalents.
Cependant, vous ne devriez pas vraiment utiliser l'un ou l'autre. La règle générale est que, à quelques exceptions près, vous devez toujours utiliser "$foo"
ou "${foo}"
et jamais $foo
ou ${foo}
. Vous devez toujours citer vos variables pour éviter d'appeler l'opérateur split + glob (plus de détails plus loin). Vous ne voulez certainement pas $foo$
. La finale $
n'est pas pertinente:
$ foo="bar"
$ echo "$foo$"
bar$
Ainsi, alors que les variables non cotées sont parfois OK:
$ echo $foo
bar
Ils ne le sont généralement pas et devraient vraiment être évités:
$ if [ -n $foo ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "$foo" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Notez que les crochets ne sont pas utiles ici non plus:
$ if [ -n ${foo} ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "${foo}" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Lorsque vous utilisez $foo
ou ${foo}
, le shell divisera la valeur enregistrée dans la variable sur les espaces blancs (cela peut être modifié en définissant la IFS
variable sur autre chose) dans une liste, puis, chaque élément de la liste est traité comme un modèle global et développé en tous les fichiers ou répertoires correspondants. Il s'agit de l' opérateur split + glob . Pour illustrer, considérons un répertoire avec deux fichiers:
$ ls -l
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file1
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file2
Maintenant, définissons une variable sur foo *
:
$ foo="foo *"
Que se passe-t-il si nous essayons de vérifier si un fichier portant ce nom existe?
$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists
La variable a été divisée en foo
et *
, comme il *
s'agit d'un caractère générique qui correspond à n'importe quelle chaîne, le shell vous indique qu'un fichier appelé foo *
exxists. Cependant, si nous le citons correctement, cela ne se produit pas:
$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file
C'était un exemple trivial pour illustrer ce point. Imaginez si j'avais utilisé rm
au lieu de echo
bien.
Donc, première règle: citez toujours vos variables. Vous pouvez utiliser soit "$foo"
ou, "${foo}"
mais le citer de toute façon. Pour plus de détails sur l'utilisation des variables en toute sécurité, consultez ces articles:
$ var="foo *"
être $ foo="foo *"
? Vous n'utilisez var
nulle part.
$
à la fin! Il sera traité comme un caractère normal et non comme faisant partie du nom de la variable.