Warum unterstützt Echo bei Verwendung des Arguments -e unter MacOSX kein "\ e" (Escape)?

36

Wenn ich versuche, farbigen Text mit ANSI-Escape-Sequenzen über den eingebauten echoBefehl auszudrucken , wird die \eEscape-Sequenz in der von mir angegebenen Zeichenfolge buchstäblich interpretiert und nicht als "Escape", das sie darstellen soll. Dies geschieht nur in Snow Leopard - die folgenden Beispiele funktionieren in Leopard wie beabsichtigt.

Anscheinend echounterstützt der -eSchalter, da er \nbei der Verwendung korrekt interpretiert wird:

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


~ $ 

Aber wenn ich versuche zu benutzen \e, bekomme ich folgendes:

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

Wie ich bereits sagte, würde mir in Leopard der obige String die Farbe "COLORS" geben.

Kennt jemand einen Grund, warum dies eine beabsichtigte Änderung sein könnte? Wie wäre es mit einer Problemumgehung für das Drucken von ANSI-Escape-Sequenzen aus Bash-Skripten auf Snow Leopard?

Die Bash-Shell-Version auf meinem Leopard-Computer ist 3.2.17(1)-releaseund 3.2.48(1)-releaseauf meinem Snow Leopard-Computer.

hasseg
quelle
1
Die Frage widerspricht dem Beitrag. In der Frage beziehen Sie sich auf / bin / echo, während Sie im Beitrag Echo ohne Pfad verwenden, was höchstwahrscheinlich das eingebaute Echo Ihrer Shell ist.
0x89
Natürlich - danke, dass Sie es bemerkt haben. Ich habe die Frage behoben, um dies zu reflektieren.
Hasseg

Antworten:

24

Ich kann Ihnen nicht sagen, warum es dieses Argument nicht unterstützt (Sie müssen möglicherweise die Programmierer danach fragen). Ich weiß nur, dass ich auf meiner Linux-Box Folgendes bekomme:

$ /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/>
  • Dies erwähnt keine \eFluchten
  • es sagt, dass es /bin/echovon Gnu Coreutils ist. Wenn Apple die Quelle seiner Unix-Systemkomponenten von Zeit zu Zeit ändert (z. B. von zsh nach bash), prüfen Sie, ob /bin/echozwischen Leopard und Snow Leopard eine Änderung stattgefunden hat. Wenn es Gnu ist, können Sie die Leute bei gnu.org fragen, warum sie sich dafür entscheiden, diese Sequenzen nicht einzuschließen.

Problemumgehungen (das ist interessanter): Nicht mit /bin/echo, aber Bashs Builtin echofunktioniert auf Linux-Boxen. Wenn sie in eine Bash ohne eingebautes Echo (oder etwas noch Dunkleres) geändert wurden, können Sie auch diese nicht weit verbreitete Funktion Ihrer Shell ausprobieren (funktioniert zumindest in Bash und Zsh):

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

Dies ist der passende Teil der bash-Manpage:

   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
quelle
4
Ich wusste nicht, dass $'string'die Fluchtsequenz aktiviert ist, danke.
Hasseg
1
\eist nicht Teil des POSIX-Standards; Die Implementierung von GNU Coreutils hat den Standard erweitert. OS X nicht.
Martijn Pieters
49

Versuchen Sie es \x1Bstatt \e.

LiraNuna
quelle
6
\x1Bstatt \efunktioniert, danke.
Hasseg
10
Als Referenz 1Bdient der Hex-Wert des Escape-Zeichens .
TachyonVortex
15

Funktioniert \033noch Wenn nicht, können Sie hoffentlich Strg + V drücken, gefolgt von der Escape-Taste (wenn ein Mac diese Tasten hat), um ein echtes Steuerzeichen in der Befehlszeile zu erstellen (was in Skripten natürlich nicht so gut funktioniert, je nach Editor).

mihi
quelle
5
\033statt \efunktioniert, danke.
Hasseg
4
Nur als Referenz 33dient der Oktalwert des Escape-Zeichens .
TachyonVortex
Nur für zukünftige Leser 033wäre eine standardisierte Schreibweise oktal.
ocodo
11

Eine andere Möglichkeit zum Drucken von ANSI-Escape-Sequenzen in der Shell ist die Verwendung von /usr/bin/printf.

hasseg
quelle
3
printf ist die portable Möglichkeit, Dinge in der Shell anzuzeigen. Es gibt zu viele Aromen von Echo ...
Mouviciel
6

Ergänzen Sie die vorhandene hilfreiche Antwort mit Hintergrundinformationen :

Wenn Sie nur mit dem Namen aufrufenecho - und nicht mit dem Pfad /bin/echo- , rufen Sie die integrierte Bash- Funktion auf und nicht das externe Dienstprogramm auf.

Das Verhalten von systemeigenen Bash-Elementen, wie z. B. integrierten Elementen, ist in der Regel im Bash-Sinne portierbar. Dies bedeutet, dass sie auf allen Plattformen, auf denen Bash ausgeführt werden kann, gleich funktionieren sollten .

\e ist eine merkwürdige Ausnahme, die 3.x Bash-Versionen unter macOS betrifft betrifft (aus rechtlichen Gründen enthält macOS seit Version 10.13.5 (High Sierra) veraltete 3.x-Versionen von Bash).

\e(und sein Alias \E) sollte funktionieren mit echo -e; \eUnterstützung wurde dem echoeingebauten in Bash 2.0 hinzugefügt . , aber aus unerklärlichen Gründen nicht in der 3.x-Version auf macOS.

\e tut in 3.x Bash-Versionen auf anderen Plattformen wie MSYS unter Windows.

Umgekehrt funktioniert es , wenn Sie einen 4.x Bash unter macOS installieren und verwenden .\e

mklement0
quelle
2

Sie könnten versuchen, sich an POSIX anzupassen: http://www.opengroup.org/onlinepubs/9699919799/

Teil OPTIONEN besagt unter anderem:

Implementations shall not support any options.
Caotic
quelle
Hier ist der direkte Link zu dem Material, von dem ich glaube, dass Sie es beabsichtigt haben: opengroup.org/onlinepubs/9699919799/utilities/echo.html
Bis auf weiteres angehalten.
Nee. Die Seite schreibt weiter: 'Wenn der erste Operand -n ist oder wenn einer der Operanden einen <Backslash> enthält, sind die Ergebnisse implementierungsdefiniert.' Auch das macOS-Echo wird interpretiert -e.
Yongwei Wu
2

Zu Ihrer Information, wir sind gerade dabei, \ e Unterstützung für / bin / echo und / usr / bin / printf in coreutils hinzuzufügen. Beachten Sie, dass die C-Standards nicht \ e angeben, aber gcc, perl, bash, ksh und tcsh dies unterstützen

Pixelbeat
quelle
0

Sie können überprüfen, ob im Menü "Ansichtsoptionen" der terminal.app die Option "Nicht-ASCII-Zeichen entziehen" deaktiviert wurde.

Tadeusz A. Kadłubowski
quelle