为什么在 MacOSX 中使用 -e 参数时 echo 不支持“\e”(转义)

has*_*seg 41 bash command-line osx-snow-leopard macos

当我尝试通过内置echo命令使用 ANSI 转义序列打印出一些彩色文本时,似乎\e我提供的字符串中的转义序列是按字面解释的,而不是它应该表示的“转义”。这仅发生在 Snow Leopard 中——下面的示例在 Leopard 中按预期工作。

显然echo确实支持-e开关,因为它\n在使用时正确解释:

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


~ $ 
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用时\e,我得到了这个:

~ $ echo -e "\e[34mCOLORS"
\e[34mCOLORS
~ $ 
Run Code Online (Sandbox Code Playgroud)

就像我说的,在 Leopard 中,上面会给我颜色字符串“COLORS”。

有谁知道这可能是有意改变的原因?在 Snow Leopard 上从 Bash 脚本打印 ANSI 转义序列的解决方法如何?

我的 Leopard 机器上的 Bash shell 版本3.2.17(1)-release3.2.48(1)-release我的 Snow Leopard 机器一样。

Lir*_*una 51

尝试\x1B代替\e.

  • 仅供参考,`1B` 是 [转义字符](http://en.wikipedia.org/wiki/Escape_character#ASCII_escape_character) 的十六进制值。 (10认同)

0x8*_*x89 26

我不能告诉你为什么它不支持这个论点(你可能不得不问程序员)。我只知道在我的 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/>
Run Code Online (Sandbox Code Playgroud)
  • 这没有提到\e转义
  • 它说它/bin/echo来自 gnu coreutils。随着苹果不时更改其 Unix 系统组件的来源(例如从 zsh 移动到 bash),请检查/bin/echoLeopard 和 Snow Leopard 之间是否有更改。如果是 gnu,您可以在 gnu.org 上询问人们为什么他们选择不包含这些序列。

至于变通方法(那更有趣):不使用/bin/echo,但 bash 的内置功能echo适用于 linux 机器。如果它们更改为没有内置 echo 的 bash(或者更晦涩的东西),您还可以尝试 shell 的这个不广为人知的功能(至少在 bash 和 zsh 中有效):

$ echo $'\e[34m''COLORS'
Run Code Online (Sandbox Code Playgroud)

这是 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.
Run Code Online (Sandbox Code Playgroud)

  • 我不知道 `$'string'` 启用了转义序列,谢谢。 (4认同)

mih*_*ihi 16

是否\033仍然有效?如果没有,您可以按 Ctrl+V 后按 Escape 键(如果 Mac 有这些键)在命令行中创建一个真正的控制字符(当然,这在脚本中效果不佳,具体取决于编辑器)

  • 仅供参考,`33` 是[转义字符](http://en.wikipedia.org/wiki/Escape_character#ASCII_escape_character) 的八进制值。 (4认同)

has*_*seg 11

在 shell 中打印 ANSI 转义序列的另一种方法是使用/usr/bin/printf.

  • printf 是在 shell 中显示内容的可移植方式。回声的味道太多了…… (3认同)

mkl*_*nt0 7

用一些背景信息补充现有的有用答案:

如果您名称调用echo- 而不是通过其路径调用/bin/echo-您正在调用 Bash内置程序而不是外部实用程序。

原生 Bash 元素(例如内置函数)的行为在 Bash 意义上通常是可移植的,这意味着它们在任何能够运行 Bash 的平台上都应该相同

\e是一个奇怪的例外,它会影响 macOS 上的 3.x Bash 版本(直到今天,从 v10.13.5(High Sierra)开始,出于法律原因,macOS 带有过时的 3.x 版本的 Bash)。

\e(及其别名\E应该echo -e; \e支持已添加到Bash 2.0 中echo内置函数中。,但莫名其妙地不在 macOS 上的 3.x 股票版本中。

\e 其他平台上的 3.x Bash 版本中确实可以工作,例如 Windows 上的 MSYS。

相反,如果您在 macOS 上安装并使用 4.x Bash,\e 则可以正常工作。