¿Qué quieres decir con 'no una línea de comando ordinaria'? echoes generalmente una concha incorporada, pero generalmente también existe /usr/bin/echo. El -eno es POSIX, pero está disponible, por ejemplo, con bash. Proporcione más detalles de lo que quiere decir con "todavía no funcionan". ¿Cuál es el comportamiento esperado?
Curiosamente, echo -- -etampoco funciona. Convencionalmente (con utilidades GNU al menos) el guión doble indica el final de las opciones, y el resto se mantiene como argumentos literales.
Wil Cooley
66
echoLocura de nuevo. Si la gente solo usara printfy nunca mirara hacia atrás.
Jens
Respuestas:
9
con nueva línea
echo -en '-e\n'
sin nueva línea
echo -e '-e\c'
con espacios alrededor:
echo '-e '
echo ' -e'
usando retroceso (gracias a Joseph R.):
echo -e ' \b-e'
(emite SPC BS - e LF, pero cuando se envía a un terminal que se procesa -ecomo BS mueve el cursor hacia atrás una columna hacia la izquierda haciendo -que se sobrescriba el SPC)
El comportamiento de bash's echoincorporado puede depender de la versión bash. También depende del entorno ( POSIXLY_CORRECT, SHELLOPTSy BASHOPTSlas variables), las opciones ( posix, xpg_echo), las opciones de generación y argv[0]( shvs bash). Aquí probado con GNU bash 4.2.53(1), compilación predeterminada, opciones predeterminadas, entorno vacío, invocado como bash. Funciona también con zsh 5.0.5.
¿Por qué estas "soluciones alternativas" ofuscadas hasta el hueso reciben votos positivos? Charles Duffy a continuación tiene la respuesta adecuada: use printf y olvídese de tales problemas de una vez por todas.
Jens
77
Jens: porque el OP preguntó cómo hacerlo con el echocomando. Actitud no necesaria.
ctc
1
echo -e ' \b-e'salidas space-backspace-dash-e. Solo se muestra en un terminal que te dará la ilusión de que es dash-e.
Stéphane Chazelas
1
@CharlesDuffy, echo -e "\0-e"hace salida NUL-dash-e. Es sólo que los terminales ignoran que carácter NUL (NULs incluso se utiliza para ser enviado a algunos terminales (que no apoyaban el control de flujo) para darles tiempo para hacer otras cosas largas como un retorno de carro. Ver la sección bajo Retrasos y relleno en terminfo(5).)
Stéphane Chazelas
25
La mejor solución es no usar echo, sino usar printfen su lugar.
printf '%s\n'-e
Esto funciona con variables arbitrarias:
var=-e
printf '%s\n'"$var"
... lo que significa que no necesita hacer ninguna preparación / modificación especial en otra parte de su código basándose en el conocimiento de que un valor será echod.
No es posible utilizar echo de forma portátil en todos los sistemas POSIX a menos que se omitan las secuencias -n (como primer argumento) y de escape.
La utilidad printf se puede usar de forma portátil para emular cualquiera de los comportamientos tradicionales de la utilidad echo de la siguiente manera (suponiendo que IFS tenga su valor estándar o no esté configurado):
El eco histórico del Sistema V y los requisitos de las implementaciones XSI en este volumen de POSIX.1-2008 son equivalentes a:
Curiosamente, la nota POSIX dice que echo -ees portátil. Dice que -ndebe evitarse, y las secuencias de escape deben evitarse. echo -eevita ambos. Pero como indica en la última parte de su respuesta, en los sistemas GNU, echono se molesta en ajustarse a POSIX de manera predeterminada, y POSIX solo observa la portabilidad en los sistemas POSIX.
hvd
@hvd, no veo -ecubierto en la parte de la especificación a la que me vinculé . ¿Podría proporcionar un enlace o cita que lo cubra?
Charles Duffy
Es la falta de una mención lo que lo dice. :) Enumera los usos que no son portátiles, y -eno se menciona, por lo que -ees portátil (nuevamente, en todos los sistemas POSIX). Para ser justos, lo que usted citó es informativo, pero el texto normativo dice lo mismo: "Si el primer operando es -n, o si alguno de los operandos contiene un carácter <backslash>, los resultados están definidos por la implementación".
hvd
2
@hvd, más bien lo contrario. Para funcionar según lo especificado, echodebe emitir todos los argumentos sin comportamiento definido de manera contraria por el estándar. Por lo tanto, a diferencia de casi todas las demás herramientas de línea de comandos cubiertas por la especificación POSIX, en echorealidad se especifica el comportamiento de los argumentos no proporcionados: imprimirlos. No hay espacio para agregar nuevas banderas sin romper las especificaciones.
Charles Duffy
2
@hvd, ... para el caso, consulte la OPTIONSsección, donde se establece en blanco y negro: Implementations shall not support any options.
Charles Duffy
9
Con GNU echo's -econ los códigos ASCII de los caracteres:
$ /bin/echo -e '\055'e
-e
055es el número octal ASCII para -(consulte man asciila referencia rápida).
/bin/echode hecho está especificado por POSIX. Sin embargo, su interpretación de las secuencias de escape octal es una extensión XSI de la especificación de referencia.
Charles Duffy
@CharlesDuffy De hecho, hablo mal. +1 para printf (mi primer pensamiento también). Dado que -ees una extensión, sin embargo, ¿hay alguna manera de forzar el comportamiento puro de POSIX echo? Eso eliminaría toda incertidumbre sobre esto, creo.
muru
2
¡Actualmente, si! La exportación POSIXLY_CORRECT=1dará como resultado un comportamiento compatible con POSIX para GNU /bin/echo.
Charles Duffy
+1 Gracias, es bueno saber para mantener sus scripts portátiles y "homebrew-independientes de Linux" (es decir, también trabajando en una estación de trabajo profesional en el trabajo).
syntaxerror
@Kusalananda se olvidó de esto.
Muru
3
Si bien la solución obvia, estándar y recomendada es usar printf, hacerlo echopuede ser bastante complicado dependiendo de la implementación ( -naunque no tanto como para ).
POSIX.2017 compatible echos
POSIX requiereecho -e salida -e<newline>. Entonces es solo
echo -e
allí. En este sentido, los compatibles con POSIX echo(la mayoría de ellos no son compatibles con POSIX en otros aspectos, la especificación POSIX es casi inútil cuando se trata de echo) incluyen:
La función echode bashcuándo se han habilitado las opciones xpg_echoy posix(en tiempo de ejecución o tiempo de compilación, como el /bin/shde Apple macOS). set -o posix; shopt -s xpg_echo(la posixopción también se puede habilitar si se invoca como sho cuando POSIXLY_CORRECTo SHELLOPTS=posixestá en el entorno).
el /bin/echode sistemas UNIX certificados (AIX, macOS, Solaris al menos) y la mayoría de los BSD
la echoconstrucción de dash, ksh88el shell Bourne, csh, tcsh, posh, rc, es, akanga
GNU echo( /bin/echoen sistemas GNU) cuando POSIXLY_CORRECTestá en el entorno.
La echoconstrucción de mkshy algunos otros pdksh-deriva cuando su posixopción está habilitada.
la echoorden interna de yashcuando $ECHO_STYLEes o bien unset o uno de SYSV, XSI, BSD, DASH,RAW
implementaciones que soportan -e
Incluye echola investigación de Unix V8 (de donde viene), GNU, busybox, la echoorden interna de bash, zsh, pdkshy sus derivados, fishalgunos ashproyectiles basados como busybox sho la shde algunos BSD, las versiones recientes de ksh93(en algunos sistemas, y con unos valores de $PATH) con su configuración predeterminada, yashcon $ECHO_STYLEuno de GNUo ZSH:
echo -e '-e\n\c'
Las implementaciones que soportan -einvariablemente soportan -n, entonces:
echo -ne '-e\n'
funcionaría también
zsh
zsh's echoes la única aplicación que sé que soporta un marcador de fin de opción ( -).
echo --e
Convirtiéndolo en el único shell tipo Bourne echoque puede generar datos arbitrarios (también porque es el único que admite bytes NUL en sus variables y los argumentos de sus incorporados) con echo -E - "$data")
Excepto por el problema de NUL-byte, otras implementaciones que pueden generar datos arbitrarios son FreeBSD o macOS /bin/echodonde puede hacer:
/bin/echo "$data
\c"
(en esa implementación, \csolo se reconoce al final y no se admite ninguna otra secuencia de escape).
Y yash's:
ECHO_STYLE=RAW echo "$data"
(aunque tenga en cuenta que las yashvariables solo pueden contener texto, por lo tanto, no secuencias de bytes arbitrarias en entornos locales donde no todas las secuencias de bytes pueden formar caracteres válidos como en aquellos que usan UTF-8 como su mapa de caracteres).
Eso no funcionará en zshdónde -está el final del delimitador de opciones o en todas las echoimplementaciones que no son compatibles -n(las que -etambién son compatibles -n)
echo
es generalmente una concha incorporada, pero generalmente también existe/usr/bin/echo
. El-e
no es POSIX, pero está disponible, por ejemplo, con bash. Proporcione más detalles de lo que quiere decir con "todavía no funcionan". ¿Cuál es el comportamiento esperado?echo -- -e
tampoco funciona. Convencionalmente (con utilidades GNU al menos) el guión doble indica el final de las opciones, y el resto se mantiene como argumentos literales.echo
Locura de nuevo. Si la gente solo usaraprintf
y nunca mirara hacia atrás.Respuestas:
con nueva línea
sin nueva línea
con espacios alrededor:
usando retroceso (gracias a Joseph R.):
(emite SPC BS - e LF, pero cuando se envía a un terminal que se procesa
-e
como BS mueve el cursor hacia atrás una columna hacia la izquierda haciendo-
que se sobrescriba el SPC)El comportamiento de
bash
'secho
incorporado puede depender de la versión bash. También depende del entorno (POSIXLY_CORRECT
,SHELLOPTS
yBASHOPTS
las variables), las opciones (posix
,xpg_echo
), las opciones de generación yargv[0]
(sh
vsbash
). Aquí probado conGNU bash 4.2.53(1)
, compilación predeterminada, opciones predeterminadas, entorno vacío, invocado comobash
. Funciona también conzsh 5.0.5
.fuente
echo -e 'x\b-e'
echo
comando. Actitud no necesaria.echo -e ' \b-e'
salidas space-backspace-dash-e. Solo se muestra en un terminal que te dará la ilusión de que es dash-e.echo -e "\0-e"
hace salidaNUL-dash-e
. Es sólo que los terminales ignoran que carácter NUL (NULs incluso se utiliza para ser enviado a algunos terminales (que no apoyaban el control de flujo) para darles tiempo para hacer otras cosas largas como un retorno de carro. Ver la sección bajo Retrasos y relleno enterminfo(5)
.)La mejor solución es no usar
echo
, sino usarprintf
en su lugar.Esto funciona con variables arbitrarias:
... lo que significa que no necesita hacer ninguna preparación / modificación especial en otra parte de su código basándose en el conocimiento de que un valor será
echo
d.Por cierto, la especificación del comando de shell POSIX para
echo
reconoce que no es portátil como implementado, y contiene una nota sobre ese tema:(Énfasis añadido).
Dicho esto, en los sistemas GNU, existe una alternativa: solicitar un comportamiento que cumpla con los estándares.
fuente
echo -e
es portátil. Dice que-n
debe evitarse, y las secuencias de escape deben evitarse.echo -e
evita ambos. Pero como indica en la última parte de su respuesta, en los sistemas GNU,echo
no se molesta en ajustarse a POSIX de manera predeterminada, y POSIX solo observa la portabilidad en los sistemas POSIX.-e
cubierto en la parte de la especificación a la que me vinculé . ¿Podría proporcionar un enlace o cita que lo cubra?-e
no se menciona, por lo que-e
es portátil (nuevamente, en todos los sistemas POSIX). Para ser justos, lo que usted citó es informativo, pero el texto normativo dice lo mismo: "Si el primer operando es -n, o si alguno de los operandos contiene un carácter <backslash>, los resultados están definidos por la implementación".echo
debe emitir todos los argumentos sin comportamiento definido de manera contraria por el estándar. Por lo tanto, a diferencia de casi todas las demás herramientas de línea de comandos cubiertas por la especificación POSIX, enecho
realidad se especifica el comportamiento de los argumentos no proporcionados: imprimirlos. No hay espacio para agregar nuevas banderas sin romper las especificaciones.OPTIONS
sección, donde se establece en blanco y negro:Implementations shall not support any options
.Con GNU
echo
's-e
con los códigos ASCII de los caracteres:055
es el número octal ASCII para-
(consulteman ascii
la referencia rápida).fuente
/bin/echo
de hecho está especificado por POSIX. Sin embargo, su interpretación de las secuencias de escape octal es una extensión XSI de la especificación de referencia.-e
es una extensión, sin embargo, ¿hay alguna manera de forzar el comportamiento puro de POSIXecho
? Eso eliminaría toda incertidumbre sobre esto, creo.POSIXLY_CORRECT=1
dará como resultado un comportamiento compatible con POSIX para GNU/bin/echo
.Si bien la solución obvia, estándar y recomendada es usar
printf
, hacerloecho
puede ser bastante complicado dependiendo de la implementación (-n
aunque no tanto como para ).POSIX.2017 compatible
echo
sPOSIX requiere
echo -e
salida-e<newline>
. Entonces es soloallí. En este sentido, los compatibles con POSIX
echo
(la mayoría de ellos no son compatibles con POSIX en otros aspectos, la especificación POSIX es casi inútil cuando se trata deecho
) incluyen:echo
debash
cuándo se han habilitado las opcionesxpg_echo
yposix
(en tiempo de ejecución o tiempo de compilación, como el/bin/sh
de Apple macOS).set -o posix; shopt -s xpg_echo
(laposix
opción también se puede habilitar si se invoca comosh
o cuandoPOSIXLY_CORRECT
oSHELLOPTS=posix
está en el entorno)./bin/echo
de sistemas UNIX certificados (AIX, macOS, Solaris al menos) y la mayoría de los BSDecho
construcción dedash
,ksh88
el shell Bourne, csh, tcsh, posh, rc, es, akangaecho
(/bin/echo
en sistemas GNU) cuandoPOSIXLY_CORRECT
está en el entorno.echo
construcción demksh
y algunos otros pdksh-deriva cuando suposix
opción está habilitada.echo
orden interna deyash
cuando$ECHO_STYLE
es o bien unset o uno deSYSV
,XSI
,BSD
,DASH
,RAW
implementaciones que soportan
-e
Incluye
echo
la investigación de Unix V8 (de donde viene), GNU, busybox, laecho
orden interna debash
,zsh
,pdksh
y sus derivados,fish
algunosash
proyectiles basados como busyboxsh
o lash
de algunos BSD, las versiones recientes deksh93
(en algunos sistemas, y con unos valores de$PATH
) con su configuración predeterminada,yash
con$ECHO_STYLE
uno deGNU
oZSH
:Las implementaciones que soportan
-e
invariablemente soportan-n
, entonces:funcionaría también
zsh
zsh
'secho
es la única aplicación que sé que soporta un marcador de fin de opción (-
).Convirtiéndolo en el único shell tipo Bourne
echo
que puede generar datos arbitrarios (también porque es el único que admite bytes NUL en sus variables y los argumentos de sus incorporados) conecho -E - "$data"
)Excepto por el problema de NUL-byte, otras implementaciones que pueden generar datos arbitrarios son FreeBSD o macOS
/bin/echo
donde puede hacer:(en esa implementación,
\c
solo se reconoce al final y no se admite ninguna otra secuencia de escape).Y
yash
's:(aunque tenga en cuenta que las
yash
variables solo pueden contener texto, por lo tanto, no secuencias de bytes arbitrarias en entornos locales donde no todas las secuencias de bytes pueden formar caracteres válidos como en aquellos que usan UTF-8 como su mapa de caracteres).fuente
Use
-n
para evitar la nueva línea:fuente
zsh
dónde-
está el final del delimitador de opciones o en todas lasecho
implementaciones que no son compatibles-n
(las que-e
también son compatibles-n
)