Вам всегда нужны кавычки вокруг переменных во всех контекстах списка , то есть везде, где переменная может быть расширена до нескольких значений, если вы не хотите, чтобы 3 побочных эффекта оставляли переменную без кавычек.
списочные контексты включают в себя аргументы для простых команд, таких как, [или echo, for i in <here>присваивания массивам ... Существуют и другие контексты, в которых переменные также должны заключаться в кавычки. Лучше всего всегда заключать в кавычки переменные, если у вас нет веских причин не делать этого.
Думайте об отсутствии кавычек (в контексте списка) как оператора split + glob .
Как будто echo $testбыл echo glob(split("$test")).
Поведение оболочки сбивает с толку большинство людей, потому что в большинстве других языков вы помещаете кавычки вокруг фиксированных строк, например puts("foo"), а не вокруг переменных (например puts(var)), в то время как в оболочке все наоборот: все является строкой в оболочке, так что кавычки вокруг всего было бы обременительно, вам echo test, вам не нужно "echo" "test". В оболочке кавычки используются для чего-то другого: предотвращают какое-то особое значение некоторых символов и / или влияют на поведение некоторых расширений.
В [ -n $test ]или echo $testоболочка разделится $test(по умолчанию на пустые места), а затем выполнит генерацию имени файла (развернет все *шаблоны '?' ... до списка подходящих файлов), а затем передаст этот список аргументов командам [или echo,
Опять же, подумайте об этом как "[" "-n" glob(split("$test")) "]". Если $testоно пустое или содержит только пробелы (spc, tab, nl), то оператор split + glob вернет пустой список, поэтому [ -n $test ]будет "[" "-n" "]", который проверяет, является ли «-n» пустой строкой или нет. Но представьте, что случилось бы, если бы $testбыло "*" или "= foo" ...
В [ -n "$test" ], [передаются четыре аргумента "[", "-n", ""и "]"(без кавычек), который является то , что мы хотим.
Независимо от того, имеет это значение echoили [нет, просто echoвыводит одно и то же, независимо от того, был ли передан пустой аргумент или нет аргумента вообще.
Смотрите также этот ответ на аналогичный вопрос для более подробной информации о [команде и [[...]]конструкции.
echo, лишние пробелы и символы новой строки будут удалены.