Вам всегда нужны кавычки вокруг переменных во всех контекстах списка , то есть везде, где переменная может быть расширена до нескольких значений, если вы не хотите, чтобы 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
, лишние пробелы и символы новой строки будут удалены.