Почему эхо не поддерживает «\ e» (escape) при использовании аргумента -e в MacOSX

36

Когда я пытаюсь распечатать некоторый цветной текст, используя escape-последовательности ANSI через встроенную echoкоманду, кажется, что \eescape-последовательность в строке, которую я предоставляю, интерпретируется буквально, а не как «escape», которое он должен представлять. Это происходит только в Snow Leopard - приведенные ниже примеры работают так, как задумано в Leopard.

Очевидно echo, поддерживает -eпереключатель, так как он правильно интерпретирует \nпри его использовании:

~ $ 
~ $ echo "\n"
\n
~ $ echo -e "\n"


~ $ 

Но когда я пытаюсь использовать \e, я получаю это:

~ $ echo -e "\e[34mCOLORS"
\e[34mCOLORS
~ $ 

Как я уже говорил, в «Леопарде» вышесказанное даст мне строку «ЦВЕТА» в цвете.

Кто-нибудь знает причину, почему это может быть предполагаемое изменение? Как насчет обходного пути для печати escape-последовательностей ANSI из сценариев Bash на Snow Leopard?

Версия оболочки Bash на моей машине Leopard есть 3.2.17(1)-releaseи 3.2.48(1)-releaseна моей машине Snow Leopard.

hasseg
источник
1
Вопрос противоречит посту. В вопросе вы ссылаетесь на / bin / echo, а в посте вы используете echo без пути, что, скорее всего, является встроенным эхо вашей оболочки.
0x89
Конечно - спасибо, что заметили. Я исправил вопрос, чтобы отразить это.
Hasseg

Ответы:

24

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

$ /bin/echo --help
Usage: /bin/echo [SHORT-OPTION]... [STRING]...
  or:  /bin/echo LONG-OPTION
Echo the STRING(s) to standard output.

  -n             do not output the trailing newline
  -e             enable interpretation of backslash escapes
  -E             disable interpretation of backslash escapes (default)
      --help     display this help and exit
      --version  output version information and exit

If -e is in effect, the following sequences are recognized:
*emphasized text*
  \0NNN   the character whose ASCII code is NNN (octal)
  \\     backslash
  \a     alert (BEL)
  \b     backspace
  \c     produce no further output
  \f     form feed
  \n     new line
  \r     carriage return
  \t     horizontal tab
  \v     vertical tab

NOTE: your shell may have its own version of echo, which usually supersedes
the version described here.  Please refer to your shell's documentation
for details about the options it supports.

Report echo bugs to bug-coreutils@gnu.org
GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
General help using GNU software: <http://www.gnu.org/gethelp/>
Report echo translation bugs to <http://translationproject.org/team/>
  • это не касается \eпобегов
  • он говорит, что это /bin/echoот gnu coreutils. Поскольку apple время от времени меняет источник своих компонентов unix-системы (например, переход от zsh к bash), проверьте, не произошло ли изменение /bin/echoмежду Leopard и Snow Leopard. Если это gnu, вы можете спросить людей на gnu.org, почему они решили не включать эти последовательности.

Что касается обходных путей (это более интересно): Не используется /bin/echo, но встроенная функция bash echoработает на Linux-боксах. Если они изменились на bash без встроенного эха (или чего-то еще более непонятного), вы также можете попробовать эту не очень известную функцию вашей оболочки (работает по крайней мере в bash и zsh):

$ echo $'\e[34m''COLORS'

Это соответствующая часть справочной страницы bash:

   Words  of  the  form  $'string' are treated specially.  The word expands to string, with
   backslash-escaped characters replaced as specified by the ANSI  C  standard.   Backslash
   escape sequences, if present, are decoded as follows:
          \a     alert (bell)
          \b     backspace
          \e     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \'     single quote
          \nnn   the  eight-bit  character whose value is the octal value nnn (one to three
                 digits)
          \xHH   the eight-bit character whose value is the hexadecimal value  HH  (one  or
                 two hex digits)
          \cx    a control-x character

   The expanded result is single-quoted, as if the dollar sign had not been present.

   A  double-quoted string preceded by a dollar sign ($) will cause the string to be trans
   lated according to the current locale.  If the current locale is C or POSIX, the  dollar
   sign  is  ignored.  If the string is translated and replaced, the replacement is double-
   quoted.
0x89
источник
4
Я не знал о том, $'string'чтобы быть escape-последовательностью, спасибо.
Hasseg
1
\eне является частью стандарта POSIX; реализация GNU coreutils расширена по стандарту. OS X не сделал.
Мартейн Питерс
49

Попробуй \x1Bвместо \e.

LiraNuna
источник
6
\x1Bвместо того, \eчтобы работать, спасибо.
Hasseg
10
Просто для справки, 1Bэто шестнадцатеричное значение символа Escape .
TachyonVortex
15

Имеет ли \033 еще работает? Если нет, то можно надеяться, что вы можете нажать Ctrl + V, а затем клавишу Escape (если у Mac есть эти клавиши), чтобы создать реальный управляющий символ в командной строке (что, конечно, не очень хорошо работает в сценариях, в зависимости от редактора)

Михи
источник
5
\033вместо того, \eчтобы работать, спасибо.
Hasseg
4
Просто для справки, 33это восьмеричное значение символа Escape .
TachyonVortex
Просто для будущего читателя ссылка 033будет стандартизированным способом записи восьмеричного.
ocodo
11

Еще один способ печати escape-последовательностей ANSI в оболочке - использование /usr/bin/printf.

hasseg
источник
3
printf - это портативный способ отображения вещей в оболочке. Есть слишком много ароматов эха ...
mouviciel
6

Чтобы дополнить существующий полезный ответ некоторой справочной информацией :

Если вы вызываете только echoпо имени - в отличие от его пути /bin/echo- вы используете встроенную Bash, а не внешнюю утилиту.

Поведение собственных элементов Bash, таких как встроенные, обычно переносимо в смысле Bash, то есть они должны работать одинаково на любой платформе, способной запускать Bash .

\e любопытное исключение, которое влияет на версии 3.x Bash на macOS (по сей день, начиная с версии 10.13.5 (High Sierra), macOS поставляется с устаревшими версиями 3.x Bash по юридическим причинам).

\e(и его псевдоним \E) должен работать с echo -e; \eдобавлена ​​поддержка echoвстроенного в Bash 2.0 . , но необъяснимо не в версии 3.x на MacOS.

\e делает работу в 3.x Bash версии на другом платформах, таких как MSYS на Windows.

И наоборот, если вы устанавливаете и используете 4.x Bash на macOS, \e это работает.

mklement0
источник
2

Они могут попытаться соответствовать POSIX: http://www.opengroup.org/onlinepubs/9699919799/

В ОПЦИИ части говорится, среди прочего:

Implementations shall not support any options.
Caotic
источник
Вот прямая ссылка на материал, который, я думаю, вы намеревались: opengroup.org/onlinepubs/9699919799/utilities/echo.html
Приостановлено до дальнейшего уведомления.
Нет. Страница продолжает писать: «Если первый операнд -n или любой из операндов содержит символ <backslash>, результаты определяются реализацией». Кроме того, эхо macOS интерпретирует -e.
Юнвэй Ву
2

К вашему сведению, мы собираемся добавить поддержку \ e в / bin / echo и / usr / bin / printf в coreutils. Обратите внимание, что стандарты C не указывают \ e, но gcc, perl, bash, ksh и tcsh поддерживают его

pixelbeat
источник
0

Вы можете проверить, не были ли отмечены «escape-не-ascii символы» в меню параметров просмотра файла Terminal.app.

Тадеуш А. Кадлубовский
источник