Из часто задаваемых вопросов по 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
.