Fondamentalement, parce qu'en des temps maintenant révolus, le comportement de test
était plus complexe et n'était pas définie de manière uniforme sur les différents systèmes (le code portable devait donc être écrit avec soin pour éviter les constructions non portables).
En particulier, avant test
était un shell intégré, il s'agissait d'un exécutable séparé (et notez que MacOS X a toujours /bin/test
y /bin/[
comme des exécutables). Lorsque c'était le cas, l'écriture :
if [ -z $variable ]
quand $variable
était vide invoquerait le programme de test via son alias [
avec 3 arguments :
argv[0] = "["
argv[1] = "-z"
argv[2] = "]"
parce que la variable était vide et qu'il n'y avait donc rien à développer. Donc, la façon sûre d'écrire le code était :
if [ -z "$variable" ]
Cela fonctionne de manière fiable, en passant 4 arguments à la fonction test
exécutable. Certes, le programme de test est intégré à la plupart des shells depuis des décennies, mais les vieux équipements ont la vie dure, tout comme les bonnes pratiques apprises il y a encore plus longtemps.
L'autre problème résolu par le préfixe X était ce qui se passait si les variables comprenaient des tirets en tête, ou contenaient des égaux ou d'autres comparateurs. Prenons un exemple qui n'est pas désespéré :
x="-z"
if [ $x -eq 0 ]
S'agit-il d'un test de chaîne vide avec un argument erroné, ou d'un test d'égalité numérique avec un premier argument non numérique ? Différents systèmes fournissaient des réponses différentes avant que POSIX ne standardise le comportement, vers 1990. Ainsi, la manière sûre de traiter ce problème était la suivante :
if [ "X$x" = "X0" ]
ou (moins souvent, d'après mon expérience, mais de manière tout à fait équivalente) :
if [ X"$x" = X"0" ]
Ce sont tous les cas limites comme celui-ci, liés à la possibilité que le test soit un exécutable séparé, qui signifient que le code shell portable utilise encore les guillemets doubles plus abondamment que ne le requièrent les shells modernes, et la notation du préfixe X a été utilisée pour s'assurer que les choses ne pouvaient pas être mal interprétées.
1 votes
Excellente question. Ce post a une bonne réponse message d'erreur du serveur