Pourquoi echo ne prend-il pas en charge “\ e” (echappe) lorsque l’argument -e est utilisé dans MacOSX

36

Lorsque j'essaie d'imprimer du texte coloré à l'aide de séquences d'échappement ANSI via la echocommande intégrée , il semble que la \eséquence d'échappement de la chaîne que je fournis soit interprétée littéralement et non comme le "échap" qu'il est censé représenter. Cela ne se produit que dans Snow Leopard - les exemples ci-dessous fonctionnent comme prévu dans Leopard.

Apparemment, echoprend en charge le -ecommutateur car il interprète correctement \nlors de son utilisation:

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


~ $ 

Mais quand j'essaye d'utiliser \e, je reçois ceci:

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

Comme je l'ai dit, dans Léopard, ce qui précède me donnerait la chaîne "COULEURS" en couleur.

Quelqu'un sait-il pourquoi ce changement pourrait être envisagé? Que diriez-vous d'une solution de contournement pour imprimer des séquences d'échappement ANSI à partir de scripts Bash sous Snow Leopard?

La version shell Bash sur ma machine Leopard est 3.2.17(1)-releaseet 3.2.48(1)-releasesur ma machine Snow Leopard.

hasseg
la source
1
La question contredit le post. Dans la question, vous faites référence à / bin / echo, tandis que dans le post, vous utilisez echo sans chemin, qui est probablement l'écho intégré de votre shell.
0x89
Bien sûr, merci de l'avoir remarqué. J'ai corrigé la question pour refléter cela.
hasseg

Réponses:

24

Je ne peux pas vous dire pourquoi il ne supporte pas cet argument (vous devrez peut-être demander aux programmeurs à ce sujet). Je sais seulement que sur ma machine Linux, je reçois ceci:

$ /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/>
  • cela ne mentionne pas les \eévasions
  • il dit que c'est /bin/echode gnu coreutils. Apple changeant de temps en temps la source de ses composants système Unix (par exemple, passer de zsh à bash), vérifiez s'il y avait un changement /bin/echoentre Leopard et Snow Leopard. Si c'est gnou, vous pouvez demander aux gens de gnu.org pourquoi ils ont choisi de ne pas inclure ces séquences.

En ce qui concerne les solutions de contournement (c'est plus intéressant): ne pas utiliser /bin/echo, mais les echofonctions intégrées de bash fonctionnent sur les boîtes Linux. S'ils changeaient en bash sans écho interne (ou quelque chose d'encore plus obscur), vous pourriez aussi essayer cette fonctionnalité peu connue de votre shell (fonctionne au moins en bash et zsh):

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

Voici la partie correspondante de la page de manuel 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
la source
4
Je ne savais pas que $'string'la séquence d'échappement était activée, merci.
hasseg
1
\ene fait pas partie du standard POSIX; l'implémentation de GNU coreutils étendue à la norme. OS X n'a ​​pas.
Martijn Pieters
49

Essayez \x1Bau lieu de \e.

LiraNuna
la source
6
\x1Bau lieu de \efonctionne, merci.
hasseg
10
Juste pour référence, 1Best la valeur hexadécimale du caractère d'échappement .
TachyonVortex
15

Fonctionne \033toujours? Sinon, vous pouvez appuyer sur Ctrl + V, suivi de la touche Échap (si un mac en a), pour créer un véritable caractère de contrôle dans la ligne de commande (ce qui ne fonctionne bien sûr pas dans les scripts, selon l'éditeur).

Mihi
la source
5
\033au lieu de \efonctionne, merci.
hasseg
4
Juste pour référence, 33est la valeur octale du caractère d'échappement .
TachyonVortex
Pour référence future, le lecteur 033serait un moyen normalisé d’écrire en octal.
octobre
11

Une autre façon d’imprimer des séquences d’échappement ANSI dans le shell consiste à utiliser /usr/bin/printf.

hasseg
la source
3
printf est le moyen portable d’afficher des choses en shell. Il y a trop de saveurs d'écho ...
mouviciel
6

Pour compléter la réponse utile existante avec quelques informations de base :

Si vous appelant echopar nom seulement - par opposition à son chemin, /bin/echo- vous invoquer le Bash builtin plutôt que l'utilitaire externe.

Le comportement des éléments Bash natifs tels que les éléments intégrés est généralement portable dans le sens Bash, ce qui signifie qu'ils doivent fonctionner de la même manière sur toute plate-forme capable d'exécuter Bash .

\eest une exception curieuse qui affecte les versions 3.x Bash sur macOS (à ce jour, à partir de la v10.13.5 (High Sierra), macOS est fourni avec des versions obsolètes de Bash 3.x, pour des raisons juridiques).

\e(et son alias \E) devrait fonctionner avec echo -e; \ele support a été ajouté à Bash 2.0echo intégré . , mais inexplicablement, dans la version stockée 3.x de macOS.

\e fait le travail 3.x versions Bash sur d' autres plates - formes, telles que MSYS sous Windows.

Inversement, si vous installez et utilisez un Bash 4.x sous macOS, \e cela fonctionnera.

mklement0
la source
2

Ils pourraient essayer de se conformer à POSIX: http://www.opengroup.org/onlinepubs/9699919799/

La partie OPTIONS indique entre autres:

Implementations shall not support any options.
Caotique
la source
Voici le lien direct vers le matériel que je pense que vous vouliez
pause jusqu'à nouvel avis.
Nan. La page continue d'écrire: "Si le premier opérande est -n, ou si l'un des opérandes contient un caractère <barre oblique inverse>, les résultats sont définis par l'implémentation." En outre, l'écho macOS interprète -e.
Yongwei Wu le
2

FYI, nous sommes sur le point d’ajouter \ e le support de / bin / echo et / usr / bin / printf dans coreutils. Notez que les standards C ne spécifient pas \ e, mais gcc, perl, bash, ksh et tcsh le supportent

pixelbeat
la source
0

Vous pouvez vérifier si les caractères d'échappement "non-ascii" ont été décochés dans le menu des options d'affichage du terminal.app.

Tadeusz A. Kadłubowski
la source