¿Cómo imprimo '-e' con echo?

8

Sé que echo -eno es un comando ordinario. Lo he intentado echo '-e'y echo \-etodavía no funcionan.

Destacados de fábrica
fuente
1
¿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?
maxschlepzig
Quiero imprimir -e usando echo. ¿Alguna sugerencia?
Lo más destacado de la fábrica el
3
considere usar printf, es más portátil.
Michael Durrant
1
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.

jimmij
fuente
+1 tambiénecho -e 'x\b-e'
Joseph R.
2
¿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.


Por cierto, la especificación del comando de shell POSIX paraecho reconoce que no es portátil como implementado, y contiene una nota sobre ese tema:

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:

printf "%b\n" "$*"

El eco BSD es equivalente a:

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

Se alienta a las nuevas aplicaciones a usar printf en lugar de echo.

(Énfasis añadido).


Dicho esto, en los sistemas GNU, existe una alternativa: solicitar un comportamiento que cumpla con los estándares.

$ POSIXLY_CORRECT=1 /bin/echo -e
-e
Charles Duffy
fuente
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).

muru
fuente
1
/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 requiere echo -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).

Stéphane Chazelas
fuente
2

Use -npara evitar la nueva línea:

$ echo -n - && echo e
-e
vishalknishad
fuente
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)
Stéphane Chazelas