5. Guillemets et apostrophes

Encadrer une chaîne de caractères par des apostrophes a pour effet de protéger les caractères spéciaux de la chaîne en empêchant leur réinterprétation ou leur expansion par le shell ou par un script shell. (Un caractère est « spécial » s'il a une autre interprétation possible en-dehors de sa valeur littérale. Par exemple, l'asterisk * représente le caractère joker dans le remplacement et dans le expressions rationnelles.)

bash$ ls -l [Vv]*
-rw-rw-r--    1 bozo  bozo       324 Apr  2 15:05 VIEWDATA.BAT
 -rw-rw-r--    1 bozo  bozo       507 May  4 14:25 vartrace.sh
 -rw-rw-r--    1 bozo  bozo       539 Apr 14 17:11 viewdata.sh


bash$ ls -l '[Vv]*'
ls: [Vv]*: No such file or directory

Certains programmes et utilitaires réinterprètent ou étendent les caractères spéciaux placés dans une chaîne de caractères entre apostrophes. Une fonction importante des apostrophes est donc de protéger du shell les paramètres dans une ligne de commande, tout en laissant au programme appelé la possibilité de les étendre et réinterpréter.

bash$ grep '[Pp]remière' *.txt
fichier1.txt:C'est la première ligne de fichier1.txt.
fichier2.txt:C'est la Première ligne de fichier2.txt.

Notez que la version sans apostrophes grep [Pp]remière *.txt fonctionne avec le shell Bash. [25]

Les guillemets peuvent supprimer l'appétit d'echo pour les nouvelles lignes.

bash$ echo $(ls -l)
total 8 -rw-rw-r-- 1 bo bo 13 Aug 21 12:57 t.sh -rw-rw-r-- 1 bo bo 78 Aug 21 12:57 u.sh


bash$ echo "$(ls -l)"
total 8
 -rw-rw-r--  1 bo bo  13 Aug 21 12:57 t.sh
 -rw-rw-r--  1 bo bo  78 Aug 21 12:57 u.sh

5.1. Placer les variables entre guillemets

Lors du référencement d'une variable, il est généralement conseillé de placer son nom entre guillemets (""). Cela empêche la réinterprétation de tous les caractères spéciaux à l'intérieur de la chaîne -- sauf $, ` (apostrophe inversée) et \ (échappement). [26] Comme $ reste interprété comme un caractère spécial, cela permet de référencer une variable entre guillemets ("$variable"), c'est-à-dire de remplacer la variable par sa valeur (voir plus haut l'Exemple 4.1, « Affectation de variable et substitution  »).

Vous pouvez utiliser les guillemets pour empêcher la coupure des mots. [27] Un argument compris entre guillemets se présente comme un seul mot, même s'il contient des espaces blancs.

Liste="un deux trois"

for a in $Liste    #  Divise la variable en plusieurs parties
                   #+ en utilisant les espaces blancs comme séparateur.
do
  echo "$a"
done
# un
# deux
# trois

echo "---"

for a in "$Liste"  # Préserve les espaces blancs dans une seule variable.
do #     ^     ^
  echo "$a"
done
# un deux trois

Un exemple plus élaboré :

variable1="une variable contenant cinq mots"
COMMANDE Ceci est $variable1    # Exécute COMMANDE avec sept arguments :
# "Ceci" "est" "une" "variable" "contenant" "cinq" "mots"

COMMANDE "Ceci est $variable1"  # Exécute COMMANDE avec un argument :
# "Ceci est une variable contenant cinq mots"


variable2=""    # Vide.

COMMANDE $variable2 $variable2 $variable2
    # Exécute COMMANDE sans arguments.
COMMANDE "$variable2" "$variable2" "$variable2"
    # Exécute COMMANDE avec trois arguments vides.
COMMANDE "$variable2 $variable2 $variable2"
    # Exécute COMMANDE avec un argument (deux espaces).

# Merci à Stéphane Chazelas.
[Astuce]

Astuce

Mettre les arguments d'une instruction echo entre guillemets est nécessaire seulement lorsque la séparation de mots ou la préservation d'espaces blancs pose problème.

Exemple 5.1. Afficher des variables bizarres

&weirdvars;

Les apostrophes (' ') opèrent de manière similaire aux guillemets mais ne permettent pas de référencer des variables car la signification spéciale de $ est désactivée. À l'intérieur des apostrophes, tous les caractères spéciaux autres que ' sont interprétés littéralement. Vous pouvez considérer que les apostrophes (« citation totale ») sont une façon plus stricte de protéger que les guillemets (« citation partielle »).

[Note]

Note

Même le caractère d'échappement (\) aboutit à une interprétation littérale avec les apostrophes.

echo "Pourquoi ne puis-je pas écrire le caractère ' avec des apostrophes"

echo

# la méthode de contournement:
echo 'Pourquoi ne puis-je pas écrire le caractère '\' "'" ' avec une apostrophe'
#    |--------------------------------------------|  |----------------------------|
# Deux chaînes chacune avec apostrophes, et, intercalés, des apostrophes.

# Exemple de Stéphane Chazelas.


[25] Sauf s'il existe un fichier nommé first dans le répertoire courant. Encore une autre raison pour placer des guillemets (merci pour cette indication, Harald Koenig).

[26]

Entourer le caractère « ! » par des guillemets ("") provoque une erreur lorsque cette expression est utilisée en ligne de commande. Elle est alors interprétée comme une commande d'historique. À l'intérieur d'un script, le problème ne se pose pas car le mécanisme d'historique de Bash est désactivé.

Un problème plus ennuyeux est le comportement apparemment incohérent de \ à l'intérieur de guillemets (""), notamment après une commande echo -e.

bash$ echo bonjour\!
bonjour!
bash$ echo "bonjour\!"
bonjour\!

bash$ echo \
>
bash$ echo "\"
>
bash$ echo \a
a
bash$ echo "\a"
\a

bash$ echo x\ty
xty
bash$ echo "x\ty"
x\ty

bash$ echo -e x\ty
xty
bash$ echo -e "x\ty"
x       y
              

Les guillemets doubles après un echo sont parfois un échappement pour \. De plus, l'option -e de echo a pour effet que « \t » est interprété en tab.

(Merci à Wayne Pollock pour nous l'avoir indiqué et à Geoff Lee et Daniel Barclay pour nous l'avoir expliqué.)

[27] Dans ce contexte, la « coupure de mots » signifie le fait de diviser la chaîne de caractères en un certain nombre d'arguments séparés.