Любые из вложенных конструкций, которые могут быть интерполированы внутри строк, могут иметь дополнительные строки внутри них: они анализируются как новый скрипт, вплоть до закрывающего маркера, и могут даже быть вложенными на нескольких уровнях глубиной. Все строки одного из них начинаются с $. Все они документированы в сочетании руководства Bash и спецификации языка команд оболочки POSIX.
Есть несколько случаев этих конструкций:
Подстановка команды$( ... ) , как вы нашли. POSIX определяет это поведение :
В $(command)форме все символы, следующие за открывающей скобкой и совпадающей с закрывающей скобкой, составляют команду. Любой действительный сценарий оболочки может быть использован для команды ...
Кавычки являются частью действительных сценариев оболочки, поэтому они допускаются с их обычным значением.
- Подстановка команд с использованием
`тоже.
Элемент "word" в экземплярах с расширенной заменой параметров, таких как${parameter:-word} . Определение «слова» является :
Последовательность символов, рассматриваемая оболочкой как единое целое
- который включает цитируемый текст и даже смешанные кавычки a"b"c'd'e- хотя фактическое поведение расширений немного более либерально, чем, например, ${x:-hello world}тоже работает.
Арифметическое расширение с помощью $(( ... )), хотя оно там в значительной степени бесполезно (но вы также можете вкладывать подстановки команд или расширения переменных, а затем использовать в них кавычки). POSIX заявляет, что :
Выражение должно обрабатываться так, как если бы оно было в двойных кавычках, за исключением того, что двойные кавычки внутри выражения специально не обрабатываются. Оболочка должна развернуть все токены в выражении для расширения параметров, подстановки команд и удаления кавычек.
так что это поведение явно требуется. Это означает, что echo "abc $((4 "*" 5))"делает арифметику, а не скупость.
Обратите внимание, что $[ ... ]арифметическое расширение старого стиля не обрабатывается одинаково: кавычки будут ошибкой, если они появятся, независимо от того, указано ли расширение в кавычках или нет. Эта форма больше не документирована и не предназначена для использования в любом случае.
- Специфичный для локали перевод с
$"..." , который фактически использует в "качестве основного элемента. $"рассматривается как единое целое.
Есть еще один случай вложенности, который вы можете не ожидать, не включая кавычки, который связан с расширением скобки : {a,b{c,d},e}расширяется до "a bc bd e". ${x:-a{b,c}d}делает не гнездо, однако; он рассматривается как подстановка параметра, давая " a{b,c", а затем " d}". Это также задокументировано :
Когда используются фигурные скобки, соответствующая конечная фигурная скобка - это первая '}', которая не экранируется обратной косой чертой или строкой в кавычках и не находится во встроенном арифметическом расширении, подстановке команд или расширении параметра.
Как правило, все конструкции с разделителями анализируют свои тела независимо от окружающего контекста (а исключения рассматриваются как ошибки ). В сущности, при просмотре $(кода подстановки команд просто просит синтаксический анализатор извлечь из тела все, что он может, как если бы это была новая программа, а затем проверяет, что ожидаемый завершающий маркер (неэкранированный )или ))или }) появляется после запуска подпарсера. из вещей, которые он может потреблять.
Если вы думаете о функционировании синтаксического анализатора с рекурсивным спуском , это просто простая рекурсия к базовому случаю. На самом деле это проще сделать, чем другим способом, если у вас вообще есть интерполяция строк. Независимо от основной техники синтаксического анализа, оболочки, поддерживающие эти конструкции, дают одинаковый результат.
Вы можете вкладывать цитаты настолько глубоко, насколько захотите, с помощью этих конструкций, и они будут работать, как и ожидалось. Нигде не запутаться, увидев цитату в середине; вместо этого это будет началом новой строки в кавычках во внутреннем контексте.