Tengo una pregunta rapida.
¿Es normal que bash (estoy usando 4.4.11) no muestra líneas / texto que está separado / finaliza con plain \r
?
Me sorprendió un poco ver este comportamiento:
$ a=$(printf "hello\ragain\rgeorge\r\n")
$ echo "$a"
george
Pero el texto "hola de nuevo" sigue ahí, de alguna manera "oculto":
$ echo "$a" |od -w32 -t x1c
0000000 68 65 6c 6c 6f 0d 61 67 61 69 6e 0d 67 65 6f 72 67 65 0d 0a
h e l l o \r a g a i n \r g e o r g e \r \n
Y tan pronto como juguemos con bash está bien ... ¿Pero es esto un riesgo potencial de seguridad? ¿Qué sucede si los contenidos de la variable "a" provienen de un mundo externo e incluyen "comandos incorrectos" en lugar de solo hola?
Otra prueba, un poco insegura esta vez:
$ a=$(printf "ls;\rGeorge\n")
$ echo "$a"
George
$ eval "$a"
0 awkprof.out event-tester.log helloworld.c oneshot.sh rightclick-tester.py tmp uinput-simple.py
<directory listing appears with an error message at the end for command George>
Imagine un oculto en rm
lugar de un oculto ls
.
Mismo comportamiento cuando se usa echo -e:
$ a=$(echo -e "ls;\rGeorge\r\n"); echo "$a"
George
¿Soy yo quien hace algo mal ...?
fuente
bash
, sin embargo; depende completamente de la terminal cómo "mostrar" el retorno de carro, o cómo mostrar los caracteres sobrescritos. Por ejemplo, sería perfectamente válido que un terminal se muestre-\r|
como algo parecido a un signo más, en lugar de solo una tubería.bash
solo escribe bytes en un archivo; depende de quien lea esos bytes interpretarlos.printf
, que es una fiesta de comando integrado (aunque también existe como un archivo ejecutable independiente), interpreta la\r
(una secuencia de dos bytes:0x5c
y0x72
y produce el retorno de carro (un solo byte:0x0d
.) Entonces, sí, el terminal interpreta el byte0x0d
de una manera especial, pero no interpreta la cadena original\r
.En el mundo de Unix, un retorno de carro (comúnmente codificado como
\r
en lenguajes de programación) es un carácter de control sin complicaciones. Puede tener retornos de carro dentro de una línea de texto, como cualquier otro carácter aparte de un avance de línea (también llamado nueva línea ), que marca el final de una línea.En particular, en un script bash, un retorno de carro es un carácter constitutivo de una palabra ordinaria, como letras y dígitos. Cualquier efecto especial del retorno de carro proviene del terminal, no del shell.
Un retorno de carro es un personaje de control . Cuando lo imprime en un terminal, en lugar de mostrar un glifo , el terminal realiza algún efecto especial. Para un retorno de carro, el efecto especial es mover el cursor al comienzo de la línea actual. Por lo tanto, si imprime una línea que contiene un retorno de carro en el medio, el efecto es que la segunda mitad se escribe sobre la primera mitad.
Varios otros caracteres de control tienen efectos especiales: el carácter de retroceso mueve el cursor una posición hacia la izquierda. El carácter de campana hace que el terminal emita un sonido o atraiga la atención del usuario. El personaje de escape comienza una secuencia de escape que puede tener todo tipo de efectos especiales.
Si muestra una salida no confiable, debe restregar o escapar de los caracteres de control. No solo retorna el carro, sino también varios otros, en particular el carácter de escape, que puede causar todo tipo de efectos negativos. Consulte ¿Puede "capturar" un archivo un riesgo potencial de seguridad? y ¿Cómo evitar ataques de secuencia de escape en terminales? para más sobre el tema
fuente
Puede ver los retornos de carro en una variable bash utilizando la
printf
función con un%q
formato.Fuentes y lecturas adicionales:
fuente