Différence entre echo -e «<string>» et echo $ «<string>»

20

Quelle est la différence entre l'utilisation

echo -e "Hello\nWorld" 

et

echo $"Hello\nWorld" 

ne sortent-ils pas tous les deux:

Hello
World
marque
la source
1
L'avez-vous essayé? Le second sort Hello\nWorld. Vous avez besoin du -ecommutateur pour interpréter les caractères d'échappement.
Becko
4
Pour le second, je soupçonne que vous vouliez l'écrire avec des guillemets simples echo $'Hello\nWorld', qui s'imprimeront sur deux lignes sous bash.
John1024
@becko, oui, je l'ai essayé et ils ont tous deux la même chose.
Mark

Réponses:

33

echo -eet echo $'...'sont tous deux similaires en ce qu'ils prennent en charge les séquences d'échappement suivantes:

  \a     alert (bell)
  \b     backspace
  \e
  \E     an escape character
  \f     form feed
  \n     new line
  \r     carriage return
  \t     horizontal tab
  \v     vertical tab
  \\     backslash
  \0nnn  the eight-bit character whose value is the octal value nnn (zero to three octal digits)
  \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
  \uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
  \UHHHHHHHH
         the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)

Ils ont des différences. En plus de ce qui précède, echo -eprend en charge:

  \c     suppress further output
  \0nnn  the eight-bit character whose value is the octal value nnn (zero to three octal digits)

En revanche, $'....'prend en charge:

 \'     single quote
 \"     double quote
 \nnn   the eight-bit character whose value is the octal value nnn (one to three digits)
 \cx    a control-x character

Notez que, entre les deux, les \cextensions sont incompatibles:

$ echo -e  'start\n\cIstop'
start
$ echo  $'start\n\cIstop'
start
        stop

Pour echo -eci-dessus, \csupprime la sortie supplémentaire, ignorant ainsi le Istop. En revanche, pour $'...', le \cIest interprété comme un onglet.

La forme visuellement similaire: $"..."

En revanche $'...', la fonction de $"..."est assez différente. Cela entraînera la traduction de la chaîne qu'il contient en fonction des paramètres régionaux actuels.

La echo -econtroverse

echo -en'est pas universellement pris en charge par les coques et beaucoup considèrent l' -eoption comme une erreur de conception. Observer:

$ ls
-e  -n
$ echo *
$ printf "%s\n" *
-e
-n

Comme vous pouvez le voir, si ce que vous imprimez echocommence par un tiret, les résultats peuvent être inattendus. À moins que vous ne soyez sûr que la première chaîne avec laquelle vous imprimerez echone commence pas par un tiret, il vaut mieux utiliser printf.

Pour ces raisons, la norme POSIX conclut :

Les nouvelles applications sont encouragées à utiliser printf au lieu d’écho.

Chet Ramey, qui maintient bashdepuis 22 ans, convient :

[N] ew code devrait utiliser printf.

John1024
la source
1
Il convient également de noter que Chet et POSIX recommandent d'utiliser printfplutôt queecho
geirha
@geirha Très bons points. Réponse mise à jour.
John1024
1
Le problème des options inattendues des globes (comme *) n'est pas spécifique à echo. Cela se produit avec n'importe quelle commande qui reconnaît les options courtes ou longues (écrites de manière traditionnelle) et prend les opérandes de nom de fichier, y comprisls . On peut dire que la situation est un peu pire avec echopuisque (comme votre source le mentionne) echon'accepte généralement pas --d'indiquer la fin des options, alors que l'on peut écrire des commandes comme ls -- *l. (Et vraiment, il faut généralement écrire des commandes de cette façon, lorsque vous utilisez des globes qui commencent par *ou -, en particulier dans les scripts.)
Eliah Kagan
Merci pour la réponse complète, j'ai un excercise pour mon cours sur les systèmes d' exploitation et je avais besoin d'imprimer un texte en utilisant la \nséquence d'échappement, donc en fait , il n'a pas d' importance si je l' utilise echo -e '...', echo $'...'ouecho $"..."
Mark