Тройной обратный слеш в Bash 'echo -e' ведет себя странно - PullRequest
0 голосов
/ 15 сентября 2018

У меня есть несколько переменных Bash для цветов терминала ANSI. Один из них - ANSI_NOCOLOR и определяется следующим образом:

ANSI_NOCOLOR="\e[0m"

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

Пример:

echo -e "command --with --many --options \\$ANSI_NOCOLOR"
echo -e "--more --options"

В результате:

command --with --many --options \e[0m
--more --options

Этот пример может быть уменьшен до:

$ echo -e "\\\e[0m"
\e[0m

Почему тройная обратная косая черта в Bash не работает так, как обычно известно из других C-подобных языков?

Ожидаемое / C-подобное поведение:

Escape-последовательности левоассоциативны. Таким образом,

  1. первые два \\ печатаются как \,
  2. оставшиеся \ делают предварительный просмотр (1), чтобы найти e для создания символа ESC.

Обход:
После некоторого строгания с обратными слешами я обнаружил, что 5 !! обратная косая черта обязательна. Я все еще хотел бы прочитать объяснение, почему оно ведет себя так, как оно есть.

$ echo -e "\\\\\e[33mfoo\e[0m"
\foo

Сложно управлять последовательностью сброса цвета, поэтому мой обходной путь использует две escape-последовательности ANSI, чтобы установить желтый цвет и вернуться к значению по умолчанию.

1 Ответ

0 голосов
/ 15 сентября 2018

Это происходит потому, что на работе существует два уровня экранирования:

  1. экранирование для строки в двойных кавычках.Этот проход распознает \\, но не \e
  2. echo -e escape-последовательности.Этот проход распознает как \\, так и \e.

Итак:

  1. Исходная строка \\\e
  2. Двойные кавычки заменяют\\, но оставляет неподдерживаемым \e один
  3. Теперь у вас есть \\e
  4. Эхо заменяет \\
  5. У вас есть \e

Это одна из многих причин, почему вы должны предпочесть printf над echo, когда любое значение может содержать обратную косую черту.

...