18

Может кто-нибудь объяснить, что происходит за кулисами в экранировании персонажей в оболочке Linux? Я попробовал следующее и много гуглил, но безуспешно понял, что (и как) происходит:

root@sv01:~# echo -e "\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\\ Hello!"
\\\ Hello!
root@sv01:~# echo -e "\n Hello!"

 Hello!
root@sv01:~# echo -e "\\n Hello!"

 Hello!
root@sv01:~# echo -e "\\\n Hello!"
\n Hello!

Я там полностью потерялся, так, например, почему три обратные косые черты дают только одну обратную косую черту? Я ожидаю: первые два будут сброшены на один, третий не найдет ничего, что можно избежать, поэтому он останется косой чертой (строка в первом эксперименте), но происходит то, что третий просто исчезает.
Почему я получаю одну обратную косую черту из четырех \ \\\\ Hello ! Я ожидаю, что каждая пара даст одну обратную косую черту -> две обратных косых черты.

И почему мне нужно три обратных слеша в последнем случае, чтобы избежать \n? что происходит на фоне побега, чтобы получить это? и чем он отличается от \\n дела?

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

1 ответ1

28

Это потому что bash и echo -e совмещены. От man 1 bash

Обратная косая черта без кавычек (\) является escape-символом. Он сохраняет буквальное значение следующего символа, за исключением <newline> . [...]

Заключение символов в двойные кавычки сохраняет буквальное значение всех символов в кавычках, за исключением $ , `, \ , […]. Обратная косая черта сохраняет свое специальное значение, только когда за ней следует один из следующих символов: $ ,`, " , \ или <newline> .

Дело в том, что обратный слэш с двойными кавычками не всегда особенный.

В общем, есть различные реализации echo , это встроенная в bash ; главное здесь это поведение:

Если действует -e , распознаются следующие последовательности:
\\
обратный слэш
[...]
\n
новая линия

Теперь мы можем расшифровать:

  1. echo -e "\ Hello!" - ничего особенного для bash , ничего особенного для echo ; \ остается.
  2. echo -e "\\ Hello!" - первый \ говорит bash чтобы относиться ко второму \ буквально; echo получает \ Hello! и действует как указано выше.
  3. echo -e "\\\ Hello!" - первый \ говорит bash чтобы относиться ко второму \ буквально; echo получает \\ Hello! и (из-за -e) он распознает \\ как \ .
  4. echo -e "\\\\ Hello!" - первый \ говорит bash чтобы относиться ко второму \ буквально; третий говорит то же самое о четвертом; echo получает \\ Hello! и (из-за -e) он распознает \\ как \ .
  5. echo -e "\\\\\ Hello!" - первый \ говорит bash чтобы трактовать второй \ буквально; третий говорит то же самое о четвертом; последний не особенный; echo получает \\\ Hello! и (из-за -e) он распознает начальный \\ как \ , последний \ остается неизменным.

И так далее. Как видите, до четырех последовательных обратных слешей дают один результат. Вот почему вам нужно (по крайней мере) девять из них, чтобы получить три. 9 = 4+4+1.

Теперь с \n:

  1. echo -e "\n Hello!" - нет ничего особенного для bash , echo получает ту же строку и (из-за -e) интерпретирует \n как новую строку.
  2. echo -e "\\n Hello!" - bash интерпретирует \\ как \ ; echo получает \n Hello! и результат такой же, как указано выше.
  3. echo -e "\\\n Hello!" - bash интерпретирует начальные \\ как \ ; echo получает \\n Hello! и (из-за -e) он интерпретирует \\ как литерал \ который должен быть напечатан.

Результаты будут отличаться с ' (из - за различное поведение bash или без -e (различного поведения echo

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .