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.
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.
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 à:
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).
/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écessiteecho -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).
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)
echo
est généralement un shell intégré, mais il y en a généralement aussi/usr/bin/echo
. Le-e
n'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?echo -- -e
cela 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.echo
la folie à nouveau. Si les gens utilisaientprintf
et ne regardaient jamais en arrière.Réponses:
avec newline
sans nouvelle ligne
avec des espaces autour:
en utilisant le retour arrière (merci à Joseph R.):
(il produit SPC BS - e LF, mais lorsqu'il est envoyé à un terminal rendu
-e
comme BS, le curseur recule d'une colonne vers la gauche, ce-
qui entraîne le remplacement du SPC)Le comportement de
bash
la commandeecho
intégrée de peut dépendre de la version de bash. Elle dépend aussi de l'environnement (POSIXLY_CORRECT
,SHELLOPTS
etBASHOPTS
variables), les options (posix
,xpg_echo
), les options de construction etargv[0]
(sh
vsbash
). Ici testé avecGNU bash 4.2.53(1)
, build par défaut, options par défaut, environnement vide, appelé commebash
. Fonctionne également aveczsh 5.0.5
.la source
echo -e 'x\b-e'
echo
commande. Attitude non nécessaire.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.echo -e "\0-e"
produit une sortieNUL-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 enterminfo(5)
.)La meilleure solution n'est pas d'utiliser
echo
, mais d'utiliser à laprintf
place.Cela fonctionne avec des variables arbitraires:
... 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
echo
d.Soit dit en passant , la spécification de commande shell POSIX pour
echo
reconnaît qu'elle n'est pas transférable telle qu'elle est implémentée et contient une note à ce sujet:(Je souligne).
Cela dit, sur les systèmes GNU, une alternative existe: demander un comportement conforme aux normes.
la source
echo -e
c'est portable. Il dit qu'il-n
faut é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,echo
cela ne dérange pas du tout de se conformer à POSIX par défaut, et POSIX note uniquement la portabilité sur les systèmes POSIX.-e
couvert dans la partie de la spécification à laquelle j'ai lié. Pourriez-vous fournir un lien ou une citation qui le couvre?-e
n'est pas mentionné, de même que-e
portable (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. "echo
doit é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.OPTIONS
section, où il est indiqué en noir et blanc:Implementations shall not support any options
.Avec GNU
echo
« s-e
avec les codes ASCII pour les caractères:055
est le numéro octal ASCII pour-
(voirman ascii
pour référence rapide).la source
/bin/echo
est 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.-e
s'agit d'une extension, existe-t-il un moyen de forcer le comportement POSIX purecho
? Je pense que cela éliminerait toute incertitude à ce sujet.POSIXLY_CORRECT=1
entraînera un comportement conforme POSIX pour les GNU/bin/echo
.Bien que la solution évidente, standard et recommandée soit à utiliser
printf
, le faire avececho
peut être assez délicat en fonction de l'implémentation (pas aussi délicat que pour-n
).Conforme à POSIX.2017
echo
sPOSIX nécessite
echo -e
une sortie-e<newline>
. Donc c'est justeLà. 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 concerneecho
):echo
intégréebash
lorsque les optionsxpg_echo
etposix
sont activées (au moment de l'exécution ou de la construction, comme pour/bin/sh
Apple macOS).set -o posix; shopt -s xpg_echo
(l'posix
option peut également être activée si elle est invoquée en tant quesh
ou quandPOSIXLY_CORRECT
ouSHELLOPTS=posix
dans l'environnement)./bin/echo
systèmes UNIX certifiés (AIX, MacOS, Solaris au moins) et la plupart des BSDsecho
construction dedash
,ksh88
le shell Bourne, csh, tcsh, chic, rc, es, akangaecho
(/bin/echo
sur les systèmes GNU) lorsquePOSIXLY_CORRECT
est dans l'environnement.echo
intégréemksh
et certains autres dérivés de pdksh lorsque leurposix
option est activée.echo
commande interne deyash
quand$ECHO_STYLE
est soit inexistant ou l' un deSYSV
,XSI
,BSD
,DASH
,RAW
implémentations qui prennent en charge
-e
Comprend
echo
de la recherche V8 Unix (où il vient), GNU, busybox, leecho
builtin debash
,zsh
,pdksh
et ses dérivés,fish
certainsash
coquillages comme à base busyboxsh
oush
de quelques BSDs, les versions récentes deksh93
(sur certains systèmes, et avec des valeurs de$PATH
) avec leurs paramètres par défaut,yash
avec l'$ECHO_STYLE
unGNU
ouZSH
:Les implémentations qui prennent en
-e
charge prennent toujours en charge-n
, donc:fonctionnerait aussi bien.
zsh
zsh
« secho
est la seule mise en œuvre que je sais que les supports d' un marqueur de fin de l' option (-
).Ce qui en fait le seul shell de type Bourne
echo
capable 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/echo
où vous pouvez faire:(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
:(mais notez que les
yash
variables 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).la source
Utilisez
-n
pour éviter les sauts de ligne:la source
zsh
là où se-
trouve le délimiteur de fin d'option ou sur toutes lesecho
implémentations qui ne prennent pas en charge-n
(celles qui le supportent-e
également-n
)