Из часто задаваемых вопросов по Bash:
Обратная косая черта (\) внутри обратных кавычек обрабатывается неочевидным способом:
$ echo "'echo \\a'" "$(echo \\a)" a \a $ echo "'echo \\\\a'" "$(echo \\\\a)" \a \\a
Но FAQ не нарушает правила разбора, которые приводят к этой разнице. Единственная релевантная цитата из man bash, которую я нашел, была:
Когда используется форма замены в стиле кавычек в старом стиле, обратный слеш сохраняет свое буквальное значение, за исключением случаев, когда следует $, 'или.
Случаи "$(echo \\a)" и "$(echo \\\\a)" достаточно просты: обратная косая черта, escape-символ, превращается в буквальную обратную реакцию. Таким образом, каждый экземпляр \\ становится \ на выходе. Но я изо всех сил пытаюсь понять аналогичную логику для случаев backtick. Что является основным правилом и как из этого вытекает наблюдаемый результат?
Наконец, связанный вопрос... Если вы не заключите в кавычки обратные ссылки, вы получите сообщение об ошибке "нет совпадения":
$ echo 'echo \\\\a'
-bash: no match: \a
Что происходит в этом случае?
обновление
Re: мой главный вопрос, у меня есть теория для набора правил, который объясняет все поведение, но все еще не понимаю, как это следует из каких-либо документированных правил в bash. Вот мои предложенные правила....
Внутри обратной косой черты обратный слеш перед персонажем просто возвращает этот символ. То есть, один обратный слеш не имеет никакого эффекта. И это верно для всех персонажей, кроме самой обратной реакции и обратных галочек. В случае самого обратного слэша \\ становится экранирующим обратным слэшем. Он избежит своего следующего персонажа.
Давайте посмотрим, как это закончится на примере:
a=xx
echo "'echo $a'" # prints the value of $a
echo "'echo \$a'" # single backslash has no effect: equivalent to above
echo "'echo \\$a'" # escaping backslash make $ literal
принтами:
xx
xx
$a
Давайте проанализируем оригинальные примеры с этой точки зрения:
echo "'echo \\a'"
Здесь \\ создает экранирующую обратную косую черту, но когда мы "убегаем" a, мы просто возвращаемся a, поэтому он печатает a.
echo "'echo \\\\a'"
Здесь первая пара \\ создает экранирующую обратную косую черту, которая применяется к \, создавая буквальную обратную косую черту. То есть первые 3 \\\ становятся одним литералом \ в выходных данных. Оставшийся \a просто производит a. Конечный результат - \a.