StackOverflow ответ с> 3.5K голосов показывает этот один вкладыш для присвоения DIR
директории текущего скрипта Баша:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
Я озадачен вложенными двойными кавычками. Насколько я могу судить, следующие фрагменты заключены в двойные кавычки:
"$( cd "
"${BASH_SOURCE[0]}"
" && pwd )"
... и все остальное справа от =
(то есть $( dirname
и )
) без кавычек. Другими словами, я предполагаю, что 2-й, 4-й и 6-й "
символы «закрывают» 1-й, 3-й и 5-й "
символы соответственно.
Я понимаю, чего "${BASH_SOURCE[0]}"
достигают двойные кавычки , но какова цель двух других пар двойных кавычек?
Если, с другой стороны (и несмотря на высокий балл голосов), приведенный выше фрагмент неверен, каков правильный путь для достижения его номинального намерения?
(Под номинальным намерением я подразумеваю: собрать значение, возвращаемое pwd
после первого cd
-ing в каталог, возвращенный dirname "${BASH_SOURCE[0]}"
, и выполнить cd
-ing в под-оболочке, чтобы $PWD
родительская оболочка осталась неизменной).
$( here, it's a subshell, but you are writing code as if you were writing it on the "first level" of the shell .... )
.lsb_dist="$(. /etc/os-release && echo "$ID")"; echo "$lsb_dist"
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
работает.Ответы:
Ваша загадка неверна в том, как
bash
(и оболочка в целом) проанализировала входные данные. В:Сначала
bash
проанализируйте правую часть присваивания одной длинной строке,$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
потому что двойные кавычки могут появляться внутри двойных кавычек .После этого
bash
начните анализ подстановки команд. Поскольку все символы, следующие за открывающей круглой скобкой и закрывающей скобкой, используются для создания команды внутри подстановки команды, вы получите:Оболочка продолжает анализ этой составной команды, разбивая ее на две части:
cd "$( dirname "${BASH_SOURCE[0]}" )"
Затем применяется то же правило синтаксического анализа
cd "$( dirname "${BASH_SOURCE[0]}" )"
, но на этот раз двойные кавычки не являются избыточными, но имеют смысл. Они предотвращают расщепление поля по результату$( dirname "${BASH_SOURCE[0]}" )
, а также расширение${BASH_SOURCE[0]}
(в отличие от самых внешних двойных кавычек, в RHS при назначении переменных нет необходимости предотвращатьsplit+glob
).Это правило применяется к подстановке команд во всех оболочках POSIX . Более подробную информацию вы можете прочитать в разделе «Распознавание токенов» спецификации POSIX .
источник
Как только кто-то внутри
$(...)
, цитирование начинается с нуля.Другими словами,
"..."
и$(...)
могут вкладываться друг в друга. Подстановка процессов,$(...)
может содержать один или несколько полных строки в двойных кавычках. Кроме того, строки в двойных кавычках могут содержать одну или несколько полных замен процесса. Но они не переплетаются. Таким образом, строка в двойных кавычках, которая начинается внутри подстановки процесса, никогда не будет выходить за ее пределы или наоборот.Итак, рассмотрим:
Внутри внутреннее
$(...)
это:В приведенном выше
${BASH_SOURCE[0]}
двойные кавычки. Любые кавычки, двойные или одинарные, за пределами$(...)
значения не имеют значения при определении${BASH_SOURCE[0]}
двойных кавычек .Внешний
$(...)
содержит:Здесь выражение
$( dirname "${BASH_SOURCE[0]}" )
в двойных кавычках. Факт, что есть кавычки вне внешнего, не$(...)
имеет значения, рассматривая то, что находится внутри этого. Тот факт, что внутри есть кавычки,$(...)
также не имеет значения.Вот как совпадают двойные кавычки:
источник
irrelevant
? За исключением самых внешних скобок, все остальные имеют свое собственное значение.$(...)
крепче, чем"..."
» не имеет смысла. Они не являются инфиксными операторами, и между ними нет иерархии (если бы существовала тогда, это означало бы, что либо кавычки не могут быть внутри скобок, либо скобки не могут быть внутри кавычек, но это не так). Технический термин таков$(…)
и"…"
гнездится.