¿A qué se expande una variable vacía sin comillas en bash?

Oct 21 2020

¿A qué valor se expande una variable no declarada y no entre comillas para devolver un estado de salida de 0?

Aquí hay un ejemplo de una situación particular con la que me encontré:

[ -n $var ]; echo $?
0

[ -n "$var" ]; echo $?
1

En ambas pruebas, la variable varno se declara. Podría haberme ahorrado la molestia probando con -z, donde entre comillas o sin comillas aparentemente no hace una diferencia, pero me encontré con esta situación particular y comencé a preguntarme. Miré más a fondo todas las expansiones que realiza bash, pero no pude encontrar ninguna explicación para este comportamiento.

Como regla general, suelo citar variables, pero espero que la razón de este comportamiento me ayude a comprender mejor las citas.

Respuestas

4 glennjackman Oct 21 2020 at 20:02

Los comandos test, [y [[actúan todos de la misma manera en que hacen cosas diferentes según la cantidad de argumentos que se les dan (excluyendo el ]/ de cierre ]]).

  • con 1 argumento, la prueba será exitosa si el argumento no está vacío
  • con 2 argumentos, los argumentos se tratan como un operador unario (como -n) y un operando.
  • con 3 argumentos, los argumentos se tratan como un operando, un operador binario (como =) y otro operando
  • más de 3 argumentos, testy [dan un error de "demasiados argumentos", y [[pueden dar un error diferente (tiene un analizador más complicado).

Ahora, mirando el [ -n $var ]ejemplo y comparándolo con la [[construcción. Dado [[que no divide palabras , sabe dónde están los valores de las variables. Cuando var="", dado [[ -n $var ]], después de la expansión de parámetros, bash verá [[ -n "" ]]cuál es claramente falso .

Pero para testy [, la división de palabras está en efecto. Así se [ -n $var ]convierte [ -n ](la cadena vacía desaparece). Ahora, [ve un argumento que no es una cadena vacía y, por lo tanto, es verdadero .

Si cita la variable:, [ -n "$var" ]obtendrá el resultado falso esperado.