765 votes

Quand faut-il mettre des accolades autour des variables de l'interpréteur de commandes ?

Dans les scripts shell, quand utilisons-nous {} lors de l'expansion des variables ?

Par exemple, j'ai vu ce qui suit :

var=10        # Declare variable

echo "${var}" # One use of the variable
echo "$var"   # Another use of the variable

Y a-t-il une différence significative, ou s'agit-il simplement d'un style ? L'un est-il préféré à l'autre ?

871voto

larsmans Points 167484

Dans cet exemple particulier, cela ne fait aucune différence. Cependant, le {} en ${} sont utiles si vous voulez développer la variable foo dans la chaîne

"${foo}bar"

depuis "$foobar" développerait plutôt la variable identifiée par foobar .

Les accolades sont aussi inconditionnellement requises lorsque :

  • l'expansion des éléments du tableau, comme dans ${array[42]}
  • en utilisant des opérations d'expansion de paramètres, comme dans ${filename%.*} (supprimer l'extension)
  • étendre les paramètres de position au-delà de 9 : "$8 $9 ${10} ${11}"

Faire cela partout, et pas seulement dans les cas potentiellement ambigus, peut être considéré comme une bonne pratique de programmation. Ceci à la fois par souci de cohérence et pour éviter des surprises telles que $foo_$bar.jpg où il n'est pas visuellement évident que le trait de soulignement fait partie du nom de la variable.

116 votes

{} est connu sous le nom de expansion de l'armature . ${} est connu sous le nom d'expansion variable. Ils font des choses différentes. Je t'aurais bien noté sauf pour la partie "pas d'expansion".

6 votes

@NewUser " Donc, à part les tableaux, ce n'est pas vraiment nécessaire. " Pas du tout, l'appareil dentaire est nécessaire pour EXPANSION DES PARAMÈTRES une construction très utile dans les scripts. J'ai vu de nombreux scripts sed et awk qui peuvent être remplacés par un peu d'expansion de paramètres.

11 votes

@caffinatedmonkey $() est utilisé pour exécuter une commande, telle que md5sum=$(md5sum foo.bin) stockera la sortie de md5sum foo.bin dans la variable md5sum maintenant accessible en utilisant ${md5sum} . Aussi, +1 et beaucoup plus dans l'esprit de l'OP pour avoir mentionné que c'est une bonne pratique d'être explicite !

140voto

Aaron McDaid Points 7761

Les variables sont déclarées et assignées sans $ et sans {} . Vous devez utiliser

var=10

à assigner. Pour lire la variable (en d'autres termes, "développer" la variable), vous devez utiliser la fonction $ .

$var      # use the variable
${var}    # same as above
${var}bar # expand var, and append "bar" too
$varbar   # same as ${varbar}, i.e expand a variable called varbar, if it exists.

Cela m'a parfois déconcerté - dans d'autres langues, nous faisons référence à la variable de la même manière, qu'elle soit à gauche ou à droite d'une affectation. Mais le shell-scripting est différent, $var=10 ne fait pas ce que vous pensez qu'il fait !

37voto

glenn jackman Points 69748

Vous utilisez {} pour le regroupement. Les accolades sont nécessaires pour déréférencer les éléments du tableau. Exemple :

dir=(*)           # store the contents of the directory into an array
echo "${dir[0]}"  # get the first entry.
echo "$dir[0]"    # incorrect

0 votes

Je n'ai pas pu comprendre la première ligne dir=(*) . Pour autant que je sache, dir est une commande intégrée pour lister le contenu des répertoires (équivalent à ls -C -b ). Pourriez-vous m'expliquer ?

1 votes

En programmation shell, les commandes et les arguments doivent être séparés les uns des autres par des espaces. Ici, vous voyez le signe égal sans espace, ce qui signifie qu'il s'agit d'une affectation de variable. dir est le nom de la variable, et les parenthèses sont utilisées pour recueillir l'expansion du nom de fichier * dans un tableau.

0 votes

@Jarvis Dans ce cas, le mot dir n'a aucune signification autre que celle d'une variable recevant une affectation. Vous pouvez le voir en utilisant foo comme variable. foo=(*); echo "${foo[2]}"

28voto

SierraX Points 61

Vous pouvez également effectuer des manipulations de texte à l'intérieur des accolades :

STRING="./folder/subfolder/file.txt"
echo ${STRING} ${STRING%/*/*}

Résultat :

./folder/subfolder/file.txt ./folder

o

STRING="This is a string"
echo ${STRING// /_}

Résultat :

This_is_a_string

Vous avez raison dans les "variables régulières" ne sont pas nécessaires.... Mais c'est plus utile pour le débogage et pour lire un script.

12voto

Sridhar-Sarnobat Points 965

La fin du nom de la variable est généralement signifiée par un espace ou une nouvelle ligne. Mais que faire si l'on ne veut pas d'espace ou de nouvelle ligne après l'impression de la valeur de la variable ? Les accolades indiquent à l'interpréteur du shell où se trouve la fin du nom de la variable.

Exemple classique 1) - variable shell sans espace de fin de ligne

TIME=10

# WRONG: no such variable called 'TIMEsecs'
echo "Time taken = $TIMEsecs"

# What we want is $TIME followed by "secs" with no whitespace between the two.
echo "Time taken = ${TIME}secs"

Exemple 2) Classpath Java avec jars versionnés

# WRONG - no such variable LATESTVERSION_src
CLASSPATH=hibernate-$LATESTVERSION_src.zip:hibernate_$LATEST_VERSION.jar

# RIGHT
CLASSPATH=hibernate-${LATESTVERSION}_src.zip:hibernate_$LATEST_VERSION.jar

(La réponse de Fred le dit déjà, mais son exemple est un peu trop abstrait).

Prograide.com

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.

Powered by:

X