Siempre necesita comillas alrededor de las variables en todos los contextos de la lista , es decir, en todas partes, la variable puede expandirse a múltiples valores a menos que desee los 3 efectos secundarios de dejar una variable sin comillas.
Los contextos de lista incluyen argumentos a comandos simples como [o echo, las for i in <here>asignaciones a matrices ... Hay otros contextos donde las variables también necesitan ser citadas. Lo mejor es siempre citar variables a menos que tenga una muy buena razón para no hacerlo.
Piense en la ausencia de comillas (en contextos de lista) como el operador split + glob .
Como si echo $testfuera echo glob(split("$test")).
El comportamiento del shell es confuso para la mayoría de las personas porque en la mayoría de los otros idiomas, se colocan comillas alrededor de cadenas fijas, como puts("foo"), y no alrededor de variables (like puts(var)), mientras que en shell es al revés: todo es una cadena en shell, por lo que poner comillas alrededor de todo sería engorroso, usted echo test, no necesita hacerlo "echo" "test". En shell, las comillas se usan para otra cosa: evitar algún significado especial de algunos caracteres y / o afectar el comportamiento de algunas expansiones.
En [ -n $test ]o echo $test, el shell se dividirá $test(en espacios en blanco por defecto), y luego realizará la generación de nombre de archivo (expandirá todos los *patrones '?' ... a la lista de archivos coincidentes), y luego pasará esa lista de argumentos a los comandos [o echo.
Nuevamente, piense en ello como "[" "-n" glob(split("$test")) "]". Si $testestá vacío o contiene solo espacios en blanco (spc, tab, nl), entonces el operador split + glob devolverá una lista vacía, por lo [ -n $test ]que será "[" "-n" "]", que es una prueba para verificar si "-n" es la cadena vacía o no. Pero imagina lo que hubiera pasado si $testfuera "*" o "= foo" ...
En [ -n "$test" ], [se pasa los cuatro argumentos "[", "-n", ""y "]"(sin las comillas), que es lo que queremos.
Ya sea que haga echoo [no la diferencia, es solo que echogenera lo mismo, ya sea que haya pasado un argumento vacío o ningún argumento.
Consulte también esta respuesta a una pregunta similar para obtener más detalles sobre el [comando y la [[...]]construcción.
echoargumento, se eliminarán los espacios adicionales y las nuevas líneas.