Проблема понимания неочевидного использования backsla sh внутри backticks - PullRequest
2 голосов
/ 22 января 2020

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

Если я это сделаю:

echo \*

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

Если я делаю:

echo \\*

, то печатается \* Это также кажется нормальным, первое backsla sh ускользает от второго.

Если я это сделаю

echo `echo \\*`

Он печатает содержимое каталога. Но, на мой взгляд, он должен печатать так же, как echo \\*, потому что когда это подставляется и передается в эхо. Я понимаю, что это неочевидное использование обратной косой черты, о которой все говорят, но я изо всех сил пытаюсь понять ПОЧЕМУ это происходит.

Также в руководстве bash написано

Когда используется форма замещения в старом стиле, backsla sh сохраняет свое буквальное значение, за исключением случаев, когда за ним следует '$', '`' или '\'.

Но это не определяет, что такое" буквальное значение на backsla sh ". Является ли он символом выхода, продолжением или просто буквально символом sh?

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

1 Ответ

4 голосов
/ 22 января 2020

Это главным образом для исторического интереса, поскольку подстановка команд `...` была заменена более чистой формой $(...). Ни один новый скрипт никогда не должен использовать обратные метки.

Вот как вы оцениваете $(command) замену

  1. Запустите команду

Вот как вы оцениваете `string` подстановка команд:

  1. Определить диапазон строки, начиная с открывающего обратного кавычка и заканчивая неэкранированным обратным трюком (поведение не определено, если этот обратный трюк находится внутри строкового литерала: оболочка обычно либо обрабатывает его как буквальный обратный тик или как закрывающий обратный тик в зависимости от реализации его синтаксического анализатора)
  2. Удалить строку, удалив обратные косые черты, которые предшествуют одному из трех символов доллару, обратному коду или обратному символу sh. Этот следующий символ затем вставляется буквально в команду. Backsla sh, за которым следует любой другой символ, останется один.
    • Например, Hello\\ World станет Hello\ World, потому что \\ будет заменено на \
    • Hello\ World также станет Hello\ World, потому что обратная коса sh сопровождаемый символом, отличным от одного из этих трех, и поэтому сохраняет свое буквальное значение просто быть бэкслой sh
    • \\\* станет \\*, поскольку \\ станет просто \ (поскольку backsla sh является одним из трех), а \* останется \* (поскольку звездочка отсутствует)
  3. Оцените результат как команду оболочки (это включает в себя следование всем обычным правилам экранирования оболочки для результата теперь неэкранированной командной строки)

Итак, чтобы оценить echo `echo \\*`:

  1. Определить диапазон строки, здесь echo \\*
  2. Отмените экранирование в соответствии с правилами цитирования обратного ключа: echo \*
  3. Оцените его как команду, которая запускает echo для вывода литерала *
  4. Поскольку результат подстановки не заключен в кавычки, результат будет ниже go:
  5. Расширение пути к каждому слову, поэтому * становится bin Desktop Downloads Photos public_html в соответствии с файлами в текущем каталоге
  6. Обратите внимание, в частности, что не - это то же самое, что замена команды backtick выводом и повторный запуск результата. Например, мы не рассматривали экранирование, кавычки и расширения в выходных данных, которые могли бы иметь простые текстовые макросы.
Передавать каждый из них в качестве аргументов следующей команде (также эхо): echo bin Desktop Downloads Photos public_html

Результатом является список файлов в текущем каталоге.

...