¿Por qué el eco no admite "\ e" (escape) cuando se usa el argumento -e en MacOSX

36

Cuando intento imprimir un texto en color usando secuencias de escape ANSI a través del echocomando incorporado , parece que la \esecuencia de escape en la cadena que proporciono se interpreta literalmente en lugar de como el "escape" que se supone que representa. Esto solo sucede en Snow Leopard: los ejemplos a continuación funcionan según lo previsto en Leopard.

Aparentemente echoes compatible con el -einterruptor, ya que se interpreta correctamente \nal usarlo:

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


~ $ 

Pero cuando trato de usar \e, obtengo esto:

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

Como dije, en Leopard, lo anterior me daría el hilo "COLORES" en color.

¿Alguien sabe de una razón por la que esto podría ser un cambio previsto? ¿Qué tal una solución alternativa para imprimir secuencias de escape ANSI de scripts Bash en Snow Leopard?

La versión de shell Bash en mi máquina Leopard es 3.2.17(1)-releasey 3.2.48(1)-releaseen mi máquina Snow Leopard.

hasseg
fuente
1
La pregunta contradice la publicación. En la pregunta te refieres a / bin / echo, mientras que en la publicación usas echo sin ruta, que probablemente sea el eco incorporado de tu shell.
0x89
Por supuesto, gracias por notarlo. Arreglé la pregunta para reflejar esto.
hasseg

Respuestas:

24

No puedo decirte por qué no admite ese argumento (es posible que tengas que preguntarle a los programadores sobre eso). Solo sé que en mi caja de Linux, obtengo esto:

$ /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 [email protected]
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/>
  • esto no menciona \eescapes
  • dice que es /bin/echode gnu coreutils. A medida que Apple cambia la fuente de sus componentes del sistema Unix de vez en cuando (por ejemplo, pasar de zsh a bash), verifique si hubo un cambio /bin/echoentre Leopard y Snow Leopard. Si es gnu, puede preguntar a las personas en gnu.org por qué eligen no incluir esas secuencias.

En cuanto a las soluciones (eso es más interesante): no se usa /bin/echo, pero bash incorporado echofunciona en cajas de Linux. Si cambiaron a bash sin eco incorporado (o algo aún más oscuro), también podría probar esta característica no muy conocida de su shell (funciona al menos en bash y zsh):

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

Esta es la parte correspondiente de la página de manual de 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
fuente
44
No estaba al tanto de la $'string'secuencia de escape habilitada, gracias.
hasseg
1
\eno es parte del estándar POSIX; la implementación de GNU coreutils extendida en el estándar. OS X no lo hizo.
Martijn Pieters
49

Intenta en \x1Blugar de \e.

LiraNuna
fuente
66
\x1Ben lugar de \efunciona, gracias.
hasseg
10
Solo como referencia, 1Bes el valor hexadecimal del personaje Escape .
TachyonVortex
15

¿ \033Aún funciona? Si no, puede presionar Ctrl + V seguido de la tecla Escape (si un mac tiene esas teclas) para crear un carácter de control real dentro de la línea de comando (que no funciona tan bien en los scripts, por supuesto, dependiendo del editor)

mihi
fuente
55
\033en lugar de \efunciona, gracias.
hasseg
44
Solo como referencia, 33es el valor octal del carácter Escape .
TachyonVortex
Solo para futuras referencias del lector 033sería una forma estandarizada de escribir octal.
ocodo
11

Otra forma de imprimir secuencias de escape ANSI en el shell es mediante el uso /usr/bin/printf.

hasseg
fuente
3
printf es la forma portátil de mostrar cosas en shell. Hay demasiados sabores de eco ...
mouviciel
6

Para complementar la útil respuesta existente con alguna información de fondo :

Si eres invocación echopor nombre solamente - en lugar de con su ruta, /bin/echo- que está invocando el Bash incorporado en lugar de la utilidad externa.

El comportamiento de los elementos nativos de Bash, como los incorporados, generalmente es portátil en un sentido de Bash, lo que significa que deberían funcionar igual en cualquier plataforma capaz de ejecutar Bash .

\ees una curiosa excepción que afecta a las versiones 3.x Bash en macOS (hasta el día de hoy, a partir de v10.13.5 (High Sierra), macOS viene con versiones desactualizadas 3.x de Bash, por razones legales).

\e(y su alias \E) deberían funcionar con echo -e; \eSe agregó soporte a la versiónecho integrada en Bash 2.0 . , pero inexplicablemente no lo hace en la versión 3.x en macOS.

\e hace el trabajo en 3.x versiones Bash en otras plataformas, como MSYS en Windows.

Por el contrario, si se instala y utiliza un 4.x Bash en MacOS, \e hace el trabajo.

mklement0
fuente
2

Pueden tratar de cumplir con POSIX: http://www.opengroup.org/onlinepubs/9699919799/

OPCIONES de parte establece entre otras cosas:

Implementations shall not support any options.
Caótico
fuente
Aquí está el enlace directo al material que creo que pretendía: opengroup.org/onlinepubs/9699919799/utilities/echo.html
hasta nuevo aviso.
No La página continúa escribiendo: 'Si el primer operando es -n, o si alguno de los operandos contiene un carácter <backslash>, los resultados están definidos por la implementación'. Además, el eco de macOS sí interpreta -e.
Yongwei Wu
2

Para su información, estamos a punto de agregar \ e soporte a / bin / echo y / usr / bin / printf en coreutils. Tenga en cuenta que los estándares C no especifican \ e, pero gcc, perl, bash, ksh y tcsh lo admiten

pixelbeat
fuente
0

Puede verificar si ,, caracteres de escape que no son ascii '' no han sido marcados en el menú de opciones de visualización de la terminal.app.

Tadeusz A. Kadłubowski
fuente