Как строки с несколькими видами кавычек интерпретируются в bash?

Чтобы дать контекст, я пытаюсь создать простую версию bash, и для этого мне нужно имитировать способ, которым bash анализирует содержимое с помощью нескольких наборов одинарных и двойных кавычек. Я не могу понять общую процедуру, с помощью которой bash обрабатывает кавычки внутри кавычек. Я заметил некоторые повторяющиеся закономерности, но до сих пор не вижу полной картины.

Например этот пример:

$ "'"ls"'"

оценивается как:

$ 'ls'

или даже этот уродливый пример:

$ "'"'"""'"ls"'"""'"'"

оценивается как:

$ '"""ls"""'

Я заметил, что возникают следующие закономерности:

  • если количество оборачивающих кавычек четное, оно оценивается исключительно по тому, что находится внутри обратных кавычек
  • если количество оборачивающих кавычек нечетное, оно оценивается как то, что находится внутри обратных кавычек включительно.

Например, даже обертывание кавычек:

$ ""'ls'""

оценивает то, что находится внутри обратных кавычек (одинарных кавычек) без самих одинарных кавычек, оценка:

$ ls

Или для нечетного количества кавычек-оболочек:

$ '''"ls"'''

он оценивает содержимое двойных кавычек включительно:

$ "ls" : command not found.

Тем не менее, я не понимаю полной картины того, как выполняется этот шаблон синтаксического анализа для более сложных кавычек внутри кавычек.

🤔 А знаете ли вы, что...
Bash - это командный интерпретатор Unix-подобных операционных систем.


1
38
1

Ответ:

Решено

Котировки обрабатываются последовательно, ища соответствующие закрывающие котировки. Все, что находится между начальной и конечной кавычками, становится одной строкой. Вложенные кавычки не имеют особого значения.

"'"ls"'"

Когда он обрабатывает первый ", он сканирует в поисках следующего ", который заканчивает строку, содержащую '.

Затем он сканирует фиксированную строку ls.

Когда он обрабатывает " после ls, он сканирует в поисках следующего ", в результате чего получается другая строка '.

Все они объединены, в результате чего получается 'ls'.

"'"'"""'"ls"'"""'"'"

"'" — это строка '.

'"""' это строка """

"ls" это строка ls

'"""' это строка """

"'" — это строка '.

Объединение их всех вместе дает '"""ls"""'

""'ls'""

"" — пустая строка. 'ls' — это строка ls. "" — еще одна пустая строка. Объединение их вместе дает ls.

'''"ls"'''

'' — пустая строка. '"ls"' — это строка "ls" (содержащая буквальные двойные кавычки). '' — пустая строка. Объединение их дает "ls". Поскольку нет команды с таким именем (включая буквальные двойные кавычки), вы получаете сообщение об ошибке.

Существуют различия между одинарными и двойными кавычками, но они не влияют ни на один из опубликованных вами примеров. См. Разница между одинарными и двойными кавычками в Bash