Citer une variable dans le script shell «if»

9

par exemple

if [ "$FOO" = "true" ]; then

contre

if [ $FOO = "true" ]; then

Quelle est la différence? Il semble que les deux déclarations fonctionnent également.

Ryan
la source
Dans Bash, utilisez des crochets doubles et vous n'avez pas besoin des guillemets et vous obtenez des avantages supplémentaires .
pause jusqu'à nouvel ordre.
@DennisWilliamson Pas tout à fait, vous avez besoin de guillemets sur le côté droit des opérateurs d'égalité et de mise en correspondance des modèles.
Gilles 'SO- arrête d'être méchant'
@ Gilles: Parfois non. Pour les chaînes littérales contenant des espaces ou de chaînes de caractères ou des variables qui contiennent des caractères glob que vous voulez être pris littéralement , le côté droit doit être cité: a='foo bar'; [[ $a == "foo bar" ]]. Cependant, une variable qui ne contient pas de caractères glob ne doit pas être: [[ $a == $a ]]. L'expansion des mots n'est pas effectuée entre crochets doubles. Et pour la correspondance des expressions rationnelles, le modèle sur le côté droit ne doit pas être cité ou il sera pris comme une chaîne littérale: [[ $a =~ .*oo.*r ]](le modèle doit être dans une variable non-citée, cependant, à la place ...
Pause jusqu'à nouvel ordre.
d'être incorporé littéralement comme ici). Pour motif glob style correspondant, les caractères glob ne doivent pas être cités, que ce soit littéral ou dans une variable: [[ $a == foo* ]]. Pouvez-vous fournir des exemples supplémentaires d'exigence de citation en plus de mon exemple de chaîne littérale?
pause jusqu'à nouvel ordre.

Réponses:

6

Si la valeur de $FOOest un seul mot qui ne contient pas de caractère générique \[*?, les deux sont identiques.

Si $FOOest non affecté, ou vide, ou plus d'un mot (c'est-à-dire, contient des espaces ou $IFS), alors la version non citée est une erreur de syntaxe. S'il se trouve que c'est juste la bonne séquence de mots (comme 0 -eq 0 -o false), le résultat pourrait être arbitraire. Par conséquent, il est recommandé de toujours citer les variables dans les scripts shell.

Incidemment, "true"n'a pas besoin d'être cité.

200_success
la source
3

Pour illustrer les problèmes que cela pourrait causer, voici quelques exemples.

Disons que nous avons deux variables comme suit:

FOO="some value"
BAR="some value"

Nous avons maintenant deux variables contenant exactement la même chaîne / valeur. Si nous avons fait quelques instructions if pour tester le résultat, dans votre cas:

if [ $FOO = "$BAR" ]; then echo "match"; else echo "no match"; fi

À ce stade, vous obtiendrez bash: [: too many arguments. Le $ FOO non coté contient maintenant trois valeurs, à savoir '[ , some , value'. [Le mot-clé test ne sait pas quoi exécuter car il s'attend à ce que le premier ou le deuxième argument soit un opérateur.

Lorsque nous citons "$ FOO", nous disons explicitement ifde regarder les bonnes valeurs là où aucun fractionnement de mot n'a lieu.

Un autre exemple:

my_file="A random file.txt"
  • faire rm $my_filesignifie supprimer «A» «aléatoire» «file.txt», ce qui en fait trois fichiers.
  • faire rm "$my_file"supprimera "Un fichier aléatoire.txt" qui crée un fichier.

J'espère que je ne vous ai pas confondu avec ces exemples.

Valentin Bajrami
la source
0

Dans ce cas précis, il n'y a pas de différence.

Cependant, si $FOOcontient un espace ou des caractères spéciaux, vous aurez un problème.

Dans le "$FOO"cas, il utilisera la variable au total, pour que la correspondance vous isole du problème d'espace.

Cependant, si vous utilisez $FOOet qu'il existe un cas particulier, cela affectera l'instruction if.

mdpc
la source