La [
commande est une commande ordinaire. Bien que la plupart des shells le fournissent de manière intégrée pour plus d’efficacité, il respecte les règles syntaxiques normales du shell. [
est exactement équivalent à test
, sauf que [
nécessite un ]
comme dernier argument et test
ne le fait pas.
Les doubles crochets [[ … ]]
sont une syntaxe spéciale. Ils ont été introduits en ksh (plusieurs années après [
), car leur utilisation [
peut être compliquée et [[
autorise de nouveaux ajouts intéressants utilisant des caractères spéciaux du shell. Par exemple, vous pouvez écrire
[[ $x = foo && $y = bar ]]
parce que la totalité de l'expression conditionnelle est analysée par le shell, alors qu'elle [ $x = foo && $y = bar ]
serait d'abord divisée en deux commandes [ $x = foo
et $y = bar ]
séparée par l' &&
opérateur. De même, les doubles crochets permettent des choses comme la syntaxe de correspondance de modèle, par exemple [[ $x == a* ]]
pour vérifier si la valeur de x
commence par a
; entre crochets simples, cela étendrait a*
la liste des fichiers dont le nom commence par a
le répertoire actuel. Les doubles crochets ont été introduits pour la première fois en ksh et ne sont disponibles qu’en ksh, bash et zsh.
Entre crochets simples, vous devez utiliser des guillemets doubles autour des substitutions de variables, comme dans la plupart des autres endroits, car ce ne sont que des arguments pour une commande (qui se trouve être la [
commande). Dans les doubles crochets, vous n'avez pas besoin de guillemets, car le shell ne scinde ni ne sculpte les mots: il analyse une expression conditionnelle, pas une commande.
Une exception est toutefois [[ $var1 = "$var2" ]]
lorsque vous avez besoin des guillemets si vous souhaitez effectuer une comparaison chaîne par octet, sinon, il $var2
s'agirait d'un modèle à comparer $var1
.
Une chose que vous ne pouvez pas faire [[ … ]]
est d’utiliser une variable en tant qu’opérateur. Par exemple, ceci est parfaitement légal (mais rarement utile):
if [ -n "$reverse_sort" ]; then op=-gt; else op=-lt; fi
…
if [ "$x" "$op" "$y" ]; then …
Dans votre exemple
dir="/home/mazimi/VirtualBox VMs"
if [ -d ${dir} ]; then …
la commande à l' intérieur de l' if
est [
avec les 4 arguments -d
, /home/mazimi/VirtualBox
, VMs
et ]
. Le shell analyse -d /home/mazimi/VirtualBox
puis ne sait pas quoi faire avec VMs
. Vous devez empêcher le fractionnement des mots ${dir}
pour obtenir une commande bien formée.
En règle générale, utilisez toujours des guillemets doubles autour des substitutions de variables et de commandes, à moins que vous ne sachiez que vous souhaitez fractionner les mots et les globuler sur le résultat. Les principaux endroits où il est prudent de ne pas utiliser les guillemets sont les suivants:
- dans une affectation:
foo=$bar
(mais notez que vous avez besoin des guillemets dans export "foo=$bar"
ou dans les affectations de tableaux, par exemple array=("$a" "$b")
);
- dans une
case
déclaration: case $foo in …
;
- double crochets , sauf sur le côté droit du
=
ou ==
opérateur ( à moins que vous ne voulez pattern matching): [[ $x = "$y" ]]
.
Dans tous ces cas, il est correct d’utiliser des guillemets doubles. Par conséquent, vous pouvez également ignorer les règles avancées et utiliser les guillemets tout le temps.