Чтобы дать контекст, я пытаюсь создать простую версию bash, и для этого мне нужно имитировать способ, которым bash анализирует содержимое с помощью нескольких наборов одинарных и двойных кавычек. Я не могу понять общую процедуру, с помощью которой bash обрабатывает кавычки внутри кавычек. Я заметил некоторые повторяющиеся закономерности, но до сих пор не вижу полной картины.
Например этот пример:
$ "'"ls"'"
оценивается как:
$ 'ls'
или даже этот уродливый пример:
$ "'"'"""'"ls"'"""'"'"
оценивается как:
$ '"""ls"""'
Я заметил, что возникают следующие закономерности:
Например, даже обертывание кавычек:
$ ""'ls'""
оценивает то, что находится внутри обратных кавычек (одинарных кавычек) без самих одинарных кавычек, оценка:
$ ls
Или для нечетного количества кавычек-оболочек:
$ '''"ls"'''
он оценивает содержимое двойных кавычек включительно:
$ "ls" : command not found.
Тем не менее, я не понимаю полной картины того, как выполняется этот шаблон синтаксического анализа для более сложных кавычек внутри кавычек.
🤔 А знаете ли вы, что...
Bash - это командный интерпретатор Unix-подобных операционных систем.
Котировки обрабатываются последовательно, ища соответствующие закрывающие котировки. Все, что находится между начальной и конечной кавычками, становится одной строкой. Вложенные кавычки не имеют особого значения.
"'"ls"'"
Когда он обрабатывает первый "
, он сканирует в поисках следующего "
, который заканчивает строку, содержащую '
.
Затем он сканирует фиксированную строку ls
.
Когда он обрабатывает "
после ls
, он сканирует в поисках следующего "
, в результате чего получается другая строка '
.
Все они объединены, в результате чего получается 'ls'
.
"'"'"""'"ls"'"""'"'"
"'"
— это строка '
.
'"""'
это строка """
"ls"
это строка ls
'"""'
это строка """
"'"
— это строка '
.
Объединение их всех вместе дает '"""ls"""'
""'ls'""
""
— пустая строка. 'ls'
— это строка ls
. ""
— еще одна пустая строка. Объединение их вместе дает ls
.
'''"ls"'''
''
— пустая строка. '"ls"'
— это строка "ls"
(содержащая буквальные двойные кавычки). ''
— пустая строка. Объединение их дает "ls"
. Поскольку нет команды с таким именем (включая буквальные двойные кавычки), вы получаете сообщение об ошибке.
Существуют различия между одинарными и двойными кавычками, но они не влияют ни на один из опубликованных вами примеров. См. Разница между одинарными и двойными кавычками в Bash