Por que o eco não suporta "\ e" (escape) ao usar o argumento -e no MacOSX

36

Quando tento imprimir algum texto colorido usando sequências de escape ANSI por meio do echocomando interno, parece que a \esequência de escape na string que forneço é interpretada literalmente em vez de como a "fuga" que deveria representar. Isso acontece apenas no Snow Leopard - os exemplos abaixo funcionam como pretendido no Leopard.

Aparentemente echo, suporta o -eswitch, pois ele interpreta corretamente \nao usá-lo:

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


~ $ 

Mas quando tento usar \e, recebo o seguinte:

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

Como eu disse, no Leopard, o texto acima me daria a sequência "COLORS" em cores.

Alguém sabe de uma razão para que isso possa ser uma mudança pretendida? Que tal uma solução alternativa para imprimir seqüências de escape ANSI de scripts Bash no Snow Leopard?

A versão do shell Bash na minha máquina Leopard é 3.2.17(1)-releasee 3.2.48(1)-releasena minha máquina Snow Leopard.

hasseg
fonte
11
A questão contradiz o post. Na pergunta, você se refere a / bin / echo, enquanto no post você usa eco sem caminho, o que provavelmente é o eco interno do seu shell.
0x89 03/09/09
Claro - obrigado por perceber. Corrigi a pergunta para refletir isso.
hasseg 5/09/09

Respostas:

24

Não sei dizer por que ele não suporta esse argumento (talvez você precise perguntar aos programadores sobre isso). Eu só sei que na minha caixa Linux, recebo o seguinte:

$ /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/>
  • isso não menciona \eescapes
  • diz que é /bin/echodo gnu coreutils. À medida que a apple altera a fonte de seus componentes do sistema unix de tempos em tempos (por exemplo, passe de zsh para bash), verifique se houve uma alteração /bin/echoentre o Leopard e o Snow Leopard. Se for gnu, você pode perguntar às pessoas no gnu.org por que elas optam por não incluir essas seqüências.

Quanto às soluções alternativas (isso é mais interessante): Não use /bin/echo, mas o built-in do bash echofunciona em caixas linux. Se eles mudaram para um bash sem eco interno (ou algo ainda mais obscuro), você também pode tentar esse recurso não conhecido do seu shell (funciona pelo menos no bash e no zsh):

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

Esta é a parte correspondente da página de manual do 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
fonte
4
Eu não estava ciente de $'string'estar habilitado para a sequência de escape, obrigado.
hasseg 5/09/09
11
\enão faz parte do padrão POSIX; a implementação do coreUtil GNU estendida no padrão. OS X não.
precisa
49

Tente em \x1Bvez de \e.

LiraNuna
fonte
6
\x1Bem vez de \efuncionar, obrigado.
hasseg 5/09/09
10
Apenas para referência, 1Bé o valor hexadecimal do caractere Escape .
TachyonVortex
15

Será que \033ainda funciona? Caso contrário, é possível pressionar Ctrl + V seguido da tecla Escape (se um mac tiver essas teclas) para criar um caractere de controle real dentro da linha de comando (o que não funciona muito bem nos scripts, é claro, dependendo do editor)

mihi
fonte
5
\033em vez de \efuncionar, obrigado.
hasseg 5/09/09
4
Apenas para referência, 33é o valor octal do caractere Escape .
TachyonVortex
Apenas para futuras referências de leitores, 033seria uma maneira padronizada de escrever octal.
Ocodo
11

Uma outra maneira de imprimir seqüências de escape ANSI no shell é usando /usr/bin/printf.

hasseg
fonte
3
printf é a maneira portátil de exibir as coisas no shell. Existem muitos sabores de eco ...
mouviciel 5/09/09
6

Para complementar a resposta útil existente com algumas informações básicas :

Se você estiver invocando apenas echopelo nome - e não pelo caminho /bin/echo- , está invocando o Bash interno, e não o utilitário externo.

O comportamento dos elementos nativos do Bash, como os builtins, geralmente é portátil no sentido do Bash, o que significa que eles devem funcionar da mesma maneira em qualquer plataforma capaz de executar o Bash .

\eé uma exceção curiosa que afeta as versões 3.x Bash no macOS (até hoje, a partir da v10.13.5 (High Sierra), o macOS vem com versões 3.x desatualizadas do Bash, por motivos legais).

\e(e seu apelido \E) deve trabalhar com echo -e; \eFoi adicionado suporte ao echobuilt-in no Bash 2.0 . , mas inexplicavelmente não está na versão 3.x do macOS.

\e faz o trabalho em 3.x versões bash em outras plataformas, como o MSYS no Windows.

Por outro lado, se você instalar e usar um 4.x Bash no MacOS, \e faz o trabalho.

mklement0
fonte
2

Eles podem tentar estar em conformidade com o POSIX: http://www.opengroup.org/onlinepubs/9699919799/

A parte OPTIONS declara, entre outras coisas:

Implementations shall not support any options.
Caótico
fonte
Aqui está o link direto para o material que acho que você pretendia: opengroup.org/onlinepubs/9699919799/utilities/echo.html
Pausado até novo aviso.
Não. A página continua a escrever: 'Se o primeiro operando for -n ou se algum dos operandos contiver um caractere <slash>, os resultados serão definidos pela implementação.' Além disso, o eco do macOS interpreta -e.
Yongwei Wu 26/07
2

Para sua informação, estamos prestes a adicionar suporte a / bin / echo e / usr / bin / printf no coreutils. Observe que os padrões C não especificam \ e, mas gcc, perl, bash, ksh e tcsh o suportam

pixelbeat
fonte
0

Você pode verificar se ,, caracteres não-ascii de escape '' foram desmarcados no menu de opções de exibição do terminal.app.

Tadeusz A. Kadłubowski
fonte