Dlaczego echo nie obsługuje „\ e” (escape) podczas używania argumentu -e w MacOSX

36

Kiedy próbuję wydrukować kolorowy tekst za pomocą sekwencji ucieczki ANSI za pomocą wbudowanego echopolecenia, wydaje się, że \esekwencja ucieczki w ciągu, który podam, jest interpretowana dosłownie zamiast jako „ucieczka”, którą ma reprezentować. Dzieje się tak tylko w systemie Snow Leopard - poniższe przykłady działają zgodnie z przeznaczeniem w systemie Leopard.

Najwyraźniej echoobsługuje -eprzełącznik, ponieważ poprawnie interpretuje \npodczas używania:

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


~ $ 

Ale kiedy próbuję użyć \e, otrzymuję to:

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

Tak jak mówiłem, u Leoparda powyższe oznaczałoby kolor sznurka „KOLORY”.

Czy ktoś zna powód, dla którego może to być zamierzona zmiana? A co z obejściem drukowania sekwencji ucieczkowych ANSI ze skryptów Bash na Snow Leopard?

Wersja powłoki bash na moim komputerze Leopard jest 3.2.17(1)-releasei 3.2.48(1)-releasena moim komputerze Snow Leopard.

hasseg
źródło
1
Pytanie jest sprzeczne z postem. W pytaniu odwołujesz się do / bin / echo, natomiast w poście używasz echa bez ścieżki, które najprawdopodobniej jest wbudowanym echem twojej powłoki.
0x89
Oczywiście - dziękuję za zauważenie. Naprawiłem pytanie, aby to odzwierciedlić.
hasseg

Odpowiedzi:

24

Nie mogę ci powiedzieć, dlaczego nie obsługuje tego argumentu (być może będziesz musiał zapytać o to programistów). Wiem tylko, że na moim Linux-ie otrzymuję to:

$ /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/>
  • nie wspomina o \eucieczkach
  • mówi, że pochodzi /bin/echoz gnu coreutils. Ponieważ Apple od czasu do czasu zmienia źródło swoich składników systemu uniksowego (np. Przejście z zsh na bash), sprawdź, czy nastąpiła zmiana /bin/echomiędzy Leopardem a Snow Leopardem. Jeśli jest to gnu, możesz zapytać ludzi na gnu.org, dlaczego zdecydowali się nie uwzględniać tych sekwencji.

Co do obejścia (to jest bardziej interesujące): Nieużywanie /bin/echo, ale wbudowane bash echodziała na polach linuksowych. Jeśli zmienili się na bash bez wbudowanego echa (lub coś jeszcze bardziej niejasnego), możesz również wypróbować tę mało znaną funkcję powłoki (działa przynajmniej w bash i zsh):

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

Oto pasująca część strony podręcznika 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
źródło
4
Dzięki, nie wiedziałem, $'string'że mogę włączyć sekwencję ucieczki.
hasseg
1
\enie jest częścią standardu POSIX; implementacja GNU coreutils została rozszerzona na ten standard. OS X nie.
Martijn Pieters
49

Spróbuj \x1Bzamiast \e.

LiraNuna
źródło
6
\x1Bzamiast \edziała, dzięki.
hasseg
10
Dla porównania, 1Bjest to wartość szesnastkowa znaku Escape .
TachyonVortex
15

Czy \033nadal działa? Jeśli nie, możesz nacisnąć Ctrl + V, a następnie klawisz Escape (jeśli Mac ma te klawisze), aby utworzyć prawdziwy znak kontrolny w wierszu poleceń (co oczywiście nie działa dobrze w skryptach, w zależności od edytora)

Mihi
źródło
5
\033zamiast \edziała, dzięki.
hasseg
4
Tylko w celach informacyjnych 33jest ósemkową wartością znaku Escape .
TachyonVortex
Dla przyszłych odniesień czytelnik 033byłby ustandaryzowanym sposobem pisania ósemki.
ocodo
11

Innym sposobem drukowania sekwencji ucieczkowych ANSI w powłoce jest użycie /usr/bin/printf.

hasseg
źródło
3
printf to przenośny sposób wyświetlania rzeczy w powłoce. Jest zbyt wiele smaków echa ...
mouviciel
6

Aby uzupełnić istniejącą pomocną odpowiedź pewnymi informacjami podstawowymi :

Jeśli jesteś Wywoływanie echoprzez nazwą tylko - w przeciwieństwie do z drogi, /bin/echo- jesteś powołując się Bash wbudowane zamiast narzędzia zewnętrznego.

Zachowanie natywnych elementów Bash, takich jak wbudowane, jest zazwyczaj przenośne w sensie Bash, co oznacza, że powinny one działać tak samo na każdej platformie obsługującej Bash .

\eto ciekawy wyjątek, który dotyczy wersji 3.x Bash na macOS (do dziś, od wersji 10.13.5 (High Sierra), macOS jest dostarczany z nieaktualnymi wersjami Bash 3.x, ze względów prawnych).

\e(i jego alias \E) powinien współpracować echo -e; \ewsparcie zostało dodane do echowbudowanego w Bash 2.0 . , ale w niewytłumaczalny sposób nie występuje w wersji podstawowej 3.x na macOS.

\e wykonuje prace w wersji 3.x Bash na innych platformach, takich jak Msys w systemie Windows.

I odwrotnie, jeśli zainstalować i używać 4.x atakujących na MacOS, \e czyni pracę.

mklement0
źródło
2

Mogą próbować dostosować się do POSIX: http://www.opengroup.org/onlinepubs/9699919799/

Część OPCJE stanowi między innymi:

Implementations shall not support any options.
Caotic
źródło
Oto bezpośredni link do materiału, który moim zdaniem zamierzałeś: opengroup.org/onlinepubs/9699919799/utilities/echo.html
Wstrzymany do odwołania.
Nie. Strona kontynuuje pisanie: „Jeśli pierwszym operandem jest -n lub jeśli dowolny z operandów zawiera znak <backlash>, wyniki są zdefiniowane w implementacji.” Ponadto echo macOS interpretuje -e.
Yongwei Wu
2

Do Twojej wiadomości, właśnie dodamy obsługę \ e do / bin / echo i / usr / bin / printf w coreutils. Zauważ, że standardy C nie określają \ e, ale gcc, perl, bash, ksh i tcsh go obsługują

pixelbeat
źródło
0

Możesz sprawdzić, czy `` znaki specjalne inne '' nie zostały zaznaczone w menu opcji widoku terminal.app.

Tadeusz A. Kadłubowski
źródło