Comment imprimer «-e» avec écho?

8

Je sais que ce echo -en'est pas une commande ordinaire. J'ai essayé echo '-e'et echo \-emais ils ne fonctionnent toujours pas.

Highlights Factory
la source
1
Que voulez-vous dire par «pas une ligne de commande ordinaire»? echoest généralement un shell intégré, mais il y en a généralement aussi /usr/bin/echo. Le -en'est pas POSIX, mais disponible par exemple avec bash. Veuillez donner plus de détails sur ce que vous entendez par «ils ne fonctionnent toujours pas». Quel est le comportement attendu?
maxschlepzig
Je veux imprimer -e en utilisant l'écho. Aucune suggestion?
Faits saillants Factory
3
pensez à utiliser printf, c'est plus portable.
Michael Durrant
1
Curieusement, echo -- -ecela ne fonctionne pas non plus. Conventionnellement (avec les utilitaires GNU au moins), le double tiret indique la fin des options, le reste étant conservé comme arguments littéraux.
Wil Cooley
6
echola folie à nouveau. Si les gens utilisaient printfet ne regardaient jamais en arrière.
Jens

Réponses:

9
  • avec newline

    echo -en '-e\n'
  • sans nouvelle ligne

    echo -e '-e\c'
  • avec des espaces autour:

    echo '-e '
    echo ' -e'
  • en utilisant le retour arrière (merci à Joseph R.):

    echo -e ' \b-e'

    (il produit SPC BS - e LF, mais lorsqu'il est envoyé à un terminal rendu -ecomme BS, le curseur recule d'une colonne vers la gauche, ce -qui entraîne le remplacement du SPC)

Le comportement de bashla commande echointégrée de peut dépendre de la version de bash. Elle dépend aussi de l'environnement ( POSIXLY_CORRECT, SHELLOPTSet BASHOPTSvariables), les options ( posix, xpg_echo), les options de construction et argv[0]( shvs bash). Ici testé avec GNU bash 4.2.53(1), build par défaut, options par défaut, environnement vide, appelé comme bash. Fonctionne également avec zsh 5.0.5.

jimmij
la source
+1 Aussiecho -e 'x\b-e'
Joseph R.
2
Pourquoi ces «solutions de contournement» obscures et laides reçoivent-elles des votes positifs? Charles Duffy ci-dessous a la bonne réponse: utilisez printf et oubliez ces problèmes une fois pour toutes.
Jens
7
Jens: parce que l'OP a demandé comment le faire avec la echocommande. Attitude non nécessaire.
ctc
1
echo -e ' \b-e'sorties space-backspace-dash-e. Uniquement affiché dans un terminal, il vous donnera l'illusion qu'il s'agit de dash-e.
Stéphane Chazelas
1
@CharlesDuffy, echo -e "\0-e"produit une sortie NUL-dash-e. Il est juste que les terminaux ignorent que le caractère NUL (NUL même utilisés pour envoyer à certains terminaux (qui ne prennent pas en charge le contrôle de flux) pour donner le temps de faire d' autres choses longues comme un retour chariot. Voir la section sous Retards et Rembourrage en terminfo(5).)
Stéphane Chazelas
25

La meilleure solution n'est pas d'utiliser echo, mais d'utiliser à la printfplace.

printf '%s\n' -e

Cela fonctionne avec des variables arbitraires:

var=-e
printf '%s\n' "$var"

... ce qui signifie que vous n'avez pas besoin de faire de préparation / modification spéciale ailleurs dans votre code en sachant qu'une valeur sera echod.


Soit dit en passant , la spécification de commande shell POSIX pourecho reconnaît qu'elle n'est pas transférable telle qu'elle est implémentée et contient une note à ce sujet:

Il n'est pas possible d'utiliser l'écho de manière portative sur tous les systèmes POSIX à moins que -n (comme premier argument) et les séquences d'échappement ne soient omis.

L'utilitaire printf peut être utilisé de manière portable pour émuler l'un des comportements traditionnels de l'utilitaire echo comme suit (en supposant que IFS a sa valeur standard ou n'est pas défini):

L'écho System V historique et les exigences sur les implémentations XSI dans ce volume de POSIX.1-2008 sont équivalentes à:

printf "%b\n" "$*"

L'écho BSD équivaut à:

if [ "X$1" = "X-n" ]
then
    shift
    printf "%s" "$*"
else
    printf "%s\n" "$*"
fi

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

(Je souligne).


Cela dit, sur les systèmes GNU, une alternative existe: demander un comportement conforme aux normes.

$ POSIXLY_CORRECT=1 /bin/echo -e
-e
Charles Duffy
la source
Fait intéressant, la note POSIX dit que echo -ec'est portable. Il dit qu'il -nfaut éviter, et les séquences d'échappement doivent être évitées. echo -eévite les deux. Mais comme vous l'indiquez dans la dernière partie de votre réponse, sur les systèmes GNU, echocela ne dérange pas du tout de se conformer à POSIX par défaut, et POSIX note uniquement la portabilité sur les systèmes POSIX.
hvd
@hvd, je ne vois pas -ecouvert dans la partie de la spécification à laquelle j'ai lié. Pourriez-vous fournir un lien ou une citation qui le couvre?
Charles Duffy
C'est l'absence de mention qui le dit. :) Il répertorie les utilisations qui ne sont pas portables, et -en'est pas mentionné, de même que -eportable (encore une fois, sur les systèmes POSIX). Pour être juste, ce que vous avez cité est informatif, mais le texte normatif dit la même chose: "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. "
hvd
2
@hvd, bien au contraire. Pour fonctionner comme spécifié, echodoit émettre tous les arguments sans comportement défini de manière contraire par la norme. Ainsi - contrairement à presque tous les autres outils de ligne de commande couverts par la spécification POSIX - spécifie enecho fait le comportement des arguments non fournis: les imprimer. Il n'y a pas de place pour ajouter de nouveaux drapeaux sans casser les spécifications.
Charles Duffy
2
@hvd, ... pour cette question, voir la OPTIONSsection, où il est indiqué en noir et blanc: Implementations shall not support any options.
Charles Duffy
9

Avec GNU echo« s -eavec les codes ASCII pour les caractères:

$ /bin/echo -e '\055'e
-e

055est le numéro octal ASCII pour -(voir man asciipour référence rapide).

muru
la source
1
/bin/echoest en effet spécifié par POSIX. Cependant, son interprétation des séquences d'échappement octales est une extension XSI de la spécification de base.
Charles Duffy
@CharlesDuffy En effet, j'ai mal parlé. +1 pour printf (ma première pensée aussi). Étant donné qu'il -es'agit d'une extension, existe-t-il un moyen de forcer le comportement POSIX pur echo? Je pense que cela éliminerait toute incertitude à ce sujet.
muru
2
En fait, oui! L'exportation POSIXLY_CORRECT=1entraînera un comportement conforme POSIX pour les GNU /bin/echo.
Charles Duffy
+1 Merci, bon à savoir pour garder vos scripts portables et "indépendants de homebrew-Linux" (c'est-à-dire également travailler sur un poste de travail professionnel au travail).
erreur de syntaxe
@Kusalananda a oublié cela.
muru
3

Bien que la solution évidente, standard et recommandée soit à utiliser printf, le faire avec echopeut être assez délicat en fonction de l'implémentation (pas aussi délicat que pour-n ).

Conforme à POSIX.2017 echo s

POSIX nécessite echo -e une sortie -e<newline>. Donc c'est juste

echo -e

Là. Les POSIX conformes echoà cet égard (la plupart d'entre eux ne sont pas conformes à POSIX à d'autres égards, la spécification POSIX est presque inutile en ce qui concerne echo):

  • la fonction echointégrée bashlorsque les options xpg_echoet posixsont activées (au moment de l'exécution ou de la construction, comme pour /bin/shApple macOS). set -o posix; shopt -s xpg_echo(l' posixoption peut également être activée si elle est invoquée en tant que shou quand POSIXLY_CORRECTouSHELLOPTS=posix dans l'environnement).
  • le /bin/echo systèmes UNIX certifiés (AIX, MacOS, Solaris au moins) et la plupart des BSDs
  • la echoconstruction de dash,ksh88 le shell Bourne, csh, tcsh, chic, rc, es, akanga
  • GNU echo( /bin/echosur les systèmes GNU) lorsquePOSIXLY_CORRECT est dans l'environnement.
  • la commande echointégrée mkshet certains autres dérivés de pdksh lorsque leur posixoption est activée.
  • la echocommande interne de yashquand $ECHO_STYLEest soit inexistant ou l' un de SYSV, XSI, BSD, DASH,RAW

implémentations qui prennent en charge -e

Comprend echode la recherche V8 Unix (où il vient), GNU, busybox, le echobuiltin de bash, zsh, pdkshet ses dérivés, fishcertains ashcoquillages comme à base busybox shou shde quelques BSDs, les versions récentes de ksh93(sur certains systèmes, et avec des valeurs de $PATH) avec leurs paramètres par défaut, yashavec l' $ECHO_STYLEun GNUou ZSH:

echo -e '-e\n\c'

Les implémentations qui prennent en -echarge prennent toujours en charge -n, donc:

echo -ne '-e\n'

fonctionnerait aussi bien.

zsh

zsh« s echoest la seule mise en œuvre que je sais que les supports d' un marqueur de fin de l' option ( -).

echo - -e

Ce qui en fait le seul shell de type Bourne echocapable de produire des données arbitraires (également parce que c'est le seul qui prend en charge les octets NUL dans ses variables et les arguments de ses commandes) avececho -E - "$data" )

À l'exception du problème d'octets NUL, les autres implémentations qui peuvent générer des données arbitraires sont FreeBSD ou macOS /bin/echooù vous pouvez faire:

/bin/echo "$data
\c"

(dans cette mise en œuvre, \c n'est reconnu qu'à la fin, et aucune autre séquence d'échappement n'est prise en charge).

Et c'est yash:

ECHO_STYLE=RAW echo "$data"

(mais notez que les yashvariables ne peuvent contenir que du texte, donc pas de séquences d'octets arbitraires dans les locales où toutes les séquences d'octets ne peuvent pas former des caractères valides comme dans ceux utilisant UTF-8 comme leur charmap).

Stéphane Chazelas
la source
2

Utilisez -npour éviter les sauts de ligne:

$ echo -n - && echo e
-e
vishalknishad
la source
Cela ne fonctionnera pas zshlà où se -trouve le délimiteur de fin d'option ou sur toutes les echoimplémentations qui ne prennent pas en charge -n(celles qui le supportent -eégalement -n)
Stéphane Chazelas