Fundamentalmente, porque en tiempos pasados, el comportamiento de test
era más complejo y no se definía uniformemente en diferentes sistemas (por lo que el código portátil debía escribirse cuidadosamente para evitar construcciones no portátiles).
En particular, antes de test
era una cáscara incorporado, fue un ejecutable independiente (y observar que MacOS X todavía tiene /bin/test
y /bin/[
como ejecutables). Cuando ese es el caso, por escrito:
if [ -z $variable ]
cuando $variable
estaba vacío sería invocar el programa de prueba a través de su alias [
con 3 argumentos:
argv[0] = "["
argv[1] = "-z"
argv[2] = "]"
porque la variable estaba vacío, así que no había nada para expandir . Por lo tanto, la manera segura de escribir el código era:
if [ -z "$variable" ]
Esto funciona de forma fiable, pasando 4 argumentos a la test
ejecutable. De acuerdo, el programa de prueba ha sido incorporado a la mayoría de los proyectiles durante décadas, pero los equipos viejos mueren mucho, y también lo hacen las buenas prácticas aprendidas incluso más tiempo atrás.
El otro problema resuelto por el prefijo X fue lo que sucedió si las variables incluyen guiones principales o contienen iguales u otros comparadores. Considere (un buen ejemplo no necesitan desesperadamente):
x="-z"
if [ $x -eq 0 ]
es que una prueba de cadena vacía con un argumento callejero (errónea), o una prueba de la igualdad numérica con un primer argumento no numérico? Diferentes sistemas proporcionaron diferentes respuestas antes de que POSIX estandarizara el comportamiento, alrededor de 1990.Por lo tanto, la manera segura de hacer frente a esto fue:
if [ "X$x" = "X0" ]
o (menos por lo general, en mi experiencia, pero completamente de forma equivalente):
if [ X"$x" = X"0" ]
Fue todos los casos extremos como éste, atado con la posibilidad de que la prueba sea un ejecutable independiente, eso significa que el código de shell portátil todavía usa comillas dobles más copiosamente de lo que las conchas modernas realmente requieren, y la notación de X-prefix se usó para asegurar que las cosas no pudieran malinterpretarse.
Gran pregunta por cierto. Esta publicación tiene una buena respuesta [serverfault post] (http://serverfault.com/questions/7503/how-to-determine-if-a-bash-variable-is-empty) – chrislovecnm