Любые из вложенных конструкций, которые могут быть интерполированы внутри строк, могут иметь дополнительные строки внутри них: они анализируются как новый скрипт, вплоть до закрывающего маркера, и могут даже быть вложенными на нескольких уровнях глубиной. Все строки одного из них начинаются с $
. Все они документированы в сочетании руководства 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}
". Это также задокументировано :
Когда используются фигурные скобки, соответствующая конечная фигурная скобка - это первая '}', которая не экранируется обратной косой чертой или строкой в кавычках и не находится во встроенном арифметическом расширении, подстановке команд или расширении параметра.
Как правило, все конструкции с разделителями анализируют свои тела независимо от окружающего контекста (а исключения рассматриваются как ошибки ). В сущности, при просмотре $(
кода подстановки команд просто просит синтаксический анализатор извлечь из тела все, что он может, как если бы это была новая программа, а затем проверяет, что ожидаемый завершающий маркер (неэкранированный )
или ))
или }
) появляется после запуска подпарсера. из вещей, которые он может потреблять.
Если вы думаете о функционировании синтаксического анализатора с рекурсивным спуском , это просто простая рекурсия к базовому случаю. На самом деле это проще сделать, чем другим способом, если у вас вообще есть интерполяция строк. Независимо от основной техники синтаксического анализа, оболочки, поддерживающие эти конструкции, дают одинаковый результат.
Вы можете вкладывать цитаты настолько глубоко, насколько захотите, с помощью этих конструкций, и они будут работать, как и ожидалось. Нигде не запутаться, увидев цитату в середине; вместо этого это будет началом новой строки в кавычках во внутреннем контексте.