2012-05-14 9 views
12

Me gustaría usar echo en bash para imprimir una cadena de caracteres seguida de solo un retorno de carro. He buscado en la página de manual y he descubierto que echo -e hará que echo interprete caracteres de escape de barra invertida. Usando lo que puedo decir echo -e 'hello\r' y se imprimirá como esto¿Cómo hacer que echo interprete escapes de barra invertida y no imprimir una nueva línea final?

$>echo -e 'hello\r' 
hello 
$> 

lo que parece que se manejó el retorno de carro correctamente. También encontré echo -n en la página del manual se detendrá echo de insertar un carácter de nueva línea y parece que funciona cuando hago esto

$>echo -n 'hello\r' 
hello\r$> 

El problema que estoy teniendo es en la combinación de ambos -e y -n. He intentado cada uno de echo -e -n 'hello\r', echo -n -e 'hello\r', echo -en 'hello\r' y echo -ne 'hello\r' y nada se imprime de este modo:

$>echo -ne 'hello\r' 
$> 

¿Hay algo que me falta aquí o puedo los -e y -n opciones no se pueden utilizar juntos?

+0

'$> echo -ne 'hello \' ' dejará el cursor al comienzo de la línea que contiene el' hola '. Entonces, si su mensaje es más largo que el '$>' que tiene aquí, sobrescribirá el saludo. –

+0

"no se imprime nada"? Seguramente obtendría '' $> llo'' porque su cadena de caracteres de 2 caracteres no sobrescribiría completamente los 5 caracteres de 'hola'. Tenga en cuenta que 'retorno de carro' no es lo mismo que 'nueva línea' (vea 'hombre ascii'). Por lo tanto, parece que ha reemplazado con éxito la nueva línea con retorno de carro, pero le sorprende que el retorno de carro no se comporte como una nueva línea. ¿Por qué querías hacer esto? Soy curioso. Además, sin las comillas, el shell interpreta la barra diagonal inversa como un carácter de escape, por lo que '\ r' simplemente se convierte en' r'. Eso significa que tu primer comando realmente imprime '' hellor'' no '' hello''. –

+0

¿Ejecutó estos comandos en el mismo shell? 'echo -n hello \ r' debería tener exactamente el mismo resultado que' echo -ne hello \ r'; ambos imprimen '' hellor'' (sin una nueva línea, por lo que el mensaje aparece como '' hellor $> ''). El '-e' es irrelevante aquí porque no hay escape de barra invertida después de que el shell lo haya eliminado. 'echo -ne 'hello \ r'' o' echo -ne hello \\ r' ambos pasan el argumento' 'hello \ r'' a 'echo'. –

Respuesta

14

Creo que está funcionando, simplemente no lo está viendo. Este es el comando:

$> echo -ne 'hello\r' 

Debido al retorno de carro (\r), que dejará el cursor al comienzo de la misma línea en el terminal donde se escribió el hello - lo que significa que tiene eso en la próxima salida de cosa a la terminal será escrito. Por lo tanto, si su solicitud actual es más larga que $> que muestra aquí, sobrescribirá por completo el hello.

Esta secuencia le permitirá ver lo que está sucediendo realmente:

echo -ne 'hello\r'; sleep 5; echo 'good-bye' 

Sin embargo, para una mejor portabilidad a otros proyectiles, que evitaría el uso de opciones de echo así. Esos son puramente bashisms, no compatibles con el estándar POSIX. Sin embargo, POSIX especifica el printf incorporado. Así que si desea mostrar cadenas sin salto de línea y el análisis de secuencias de barras invertidas, que sólo puede usarlo:

printf '%s\r' 'hello' 
+0

Sí, eso fue todo. Gracias – seanwatson

1

Citando. Es la ola del futuro. Siempre cita.

echo -ne 'hello\r' 

Use comillas dobles si se pone una variable dentro que desea que se expandió.

+0

Las cotizaciones tampoco funcionan. Cuando uso citas, nada se imprime. Actualizaré la pregunta para ese – seanwatson

+0

@ swatso33: Funciona para mí. ¿Qué obtienes cuando intentas: 'echo" $ BASH_VERSION "' –

+0

Su versión '4.2.24 (2) -release'. Correr en Arch Linux si hace la diferencia. Debe ser mi versión entonces. ¿En qué versión lo estás trabajando? – seanwatson

10

Existen numerosas implementaciones diferentes de la orden echo. Hay uno integrado en la mayoría de los shells (con comportamiento diferente para cada uno), y el comportamiento de /bin/echo varía considerablemente de un sistema a otro.

En lugar de echo, utilice printf. Está integrado en bash y está disponible como un comando externo, y su comportamiento es mucho más uniforme en todas las implementaciones. (La principal variación es que GNU coreutils printf reconoce --help y --version opciones.)

sólo tiene que utilizar:

printf 'hello\r' 
+2

+1 'echo' está bien para imprimir líneas únicas, pero tan pronto como utilizas cualquier opción especial o escapes se vuelve poco fiable y poco portátil. 'printf' es mucho mejor para algo como esto. –

+0

Sin embargo, la pregunta está etiquetada como bash-specific. Parece probable que el OP no necesita portabilidad para su caso de uso. –

6

me gustaría que se introduce a printf.

OP, cumplir printf. printf. Esta es la OP ...

Cuando intente hacer algo inusual con salida en BASH, debe cambiar a printf. De hecho, utilizo printf todo el tiempo, por lo que mis scripts se ejecutarán tanto en BASH como en Kornshell.

Aunque BASH y Kornshell son 99% iguales, el comando echo es diferente. En Kornshell, está en desuso, y se supone que debes usar el built-in print. Sin embargo, no hay print en BASH. El uso de printf resuelve el problema porque funciona (más o menos) igual en ambos shells.

Dado que printf no finaliza automáticamente cada línea con un \n, no tiene que preocuparse por cómo evitar que se anexe el \n. Diablos, si quieres un \n, tienes que ponerlo tú mismo. En su caso:

printf `hello\r` 

Sin embargo, por razones de seguridad, que realmente debería hacer esto:

printf '%s\r' 'hello' 

Este es un hábito que he recibido en cuando estoy usando printf. Imagínese si quiero imprimir $FOO, y hago esto:

printf "$FOO\n" 

que normalmente va a funcionar, pero lo que si $FOO tiene un guión al principio, o tiene un signo % en ella. Lo anterior no hará lo que quiero hacer. Sin embargo, si hago esto:

printf '%s\n' "$FOO" 

Esto imprimirá $FOO no importa lo $FOO tiene en ella.

+0

FYI, su primer ejemplo de 'printf' tiene retrocesos en lugar de apóstrofos. –

1

POSIX 7 says it is not possible:

Si el primer operando es -n, o si alguno de los operandos contienen un carácter de barra invertida, los resultados son definido por la implementación.

En Ubuntu 12.04, por ejemplo:

  • de Bash eco incorporado echo -e '\n' interpreta la nueva línea, echo '\n' no.
  • /bin/sh's echo no tiene la opción -e, e interpreta la nueva línea incluso sin ella. Esto puede byte al escribir Makefile s, que usa /bin/sh por defecto.

POSIX 7 solución: printf como los otros mencionados.

+0

Eso es POSIX; OP preguntó sobre bash específicamente. Y el comportamiento de 'echo' * en bash * está bien definido y documentado, incluidas las opciones' -e' y '-n' y el tratamiento de las barras diagonales inversas. –

+0

@Mark Reed Nunca dije lo contrario. Pero muchos Googlers que vienen aquí también pueden estar interesados ​​en el comportamiento POSIX. –

Cuestiones relacionadas