¿Por qué (y cómo) estropeó el terminal el uso de cat en archivos binarios?


8

Si entiendo el catmanual correctamente:

concatenar archivos e imprimir en la salida estándar

cattomará los archivos como argumento y los imprimirá en la salida estándar.
Lo que no entiendo es si uso el comando:

cat img.png > copy.png

Obtendré 2 archivos png idénticos mientras que si solo

cat img.png  

Tengo todas las posibilidades de que mi terminal se estropee y malinterprete lo que escribo.

  • ¿Como es eso posible?
  • Los valores binarios siguen siendo datos binarios. ¿Por qué no muestra simplemente una serie de 0 y 1 o la interpretación de esos datos binarios en ASCII o lo que sea la codificación en el terminal?
  • ¿También es posible este comportamiento al catcrear un archivo de texto que contiene caracteres extraños?
  • ¿Debería implementarse un mecanismo para prevenir este comportamiento como la declaración try {} catch {}?

2
Su terminal no se estropea. Está en un estado en el que lo forzó enviándole caracteres de control. El hecho de que no pueda usarlo más después de cambiar el estado podría no ser lo que deseaba, pero es completamente el resultado de que no comprende las consecuencias de sus acciones. Ese sería el mismo que el cambio de su color de fuente a verde en un procesador de textos y diciendo su procesador de textos está en mal estado, sólo porque usted no sabe cómo cambiar de nuevo a la fuente negro, sin salir del programa, por ejemplo.
Anthon

44
un resetcomando puede ayudar a veces, pero esta no es una solución milagrosa.
Ouki

La secuencia real para escribir es Control-J reset Control-J. Casi siempre restaura la cordura.
Joshua

1
@Joshua ¿Y cuál es la diferencia entre una pulsación de tecla Ctrl-J resety una resetsola? No puedo ver ninguna (ni ninguna razón para ir por el camino más complicado)
SyntaxError

1
Porque si el terminal se dejó en modo RAW, Enter genera Ctrl-M en lugar de Ctrl-J para que el shell no vea la pulsación de tecla necesaria para finalizar una línea y ejecutar el comando.
Joshua

Respuestas:


8

cat concatena los archivos dados como argumentos en la línea de comando a la salida estándar, lee bytes a la vez y, por defecto, no realiza ninguna interpretación de los bytes que lee.

En su primer ejemplo, está redirigiendo stdout a un archivo, por eso obtiene un nuevo archivo.

En su segundo ejemplo, los bytes se escriben en el terminal, y es el terminal el que interpreta las secuencias de caracteres como secuencias de control para el terminal, es por eso que obtiene un comportamiento inusual en su terminal. No tiene nada que ver catcomo tal, catno sabe qué va a hacer con su salida. Puede enviarlo a través de una tubería a otro programa para interpretar / procesar / imprimir o jugar "Cantando bajo la lluvia".

Entonces, siguiendo la filosofía de Unix,

haz una cosa, haz una sola cosa, pero hazlo bien

cat no debe intentar adivinar lo que está tratando de hacer.

editar 1 respuesta al primer comentario de @ kiwy a continuación.

Sí y no, déjame explicarte,

No, si está caten un terminal, porque (el software del terminal) está enviando la salida a su pantalla o está interpretando secuencias de control (está emulando una pieza de hardware antigua, es decir, un dispositivo de teletipo ).

pero,

Sí, si se conecta a una tubería y el programa receptor puede interpretar los caracteres como comandos.

mira cat esto como un ejemplo, cat anyOldShellScript | bashbash interpretará lo que se obtiene como comandos.


¿significa que si usted puede interpretar catun archivo binario que puede contener instrucciones de texto sin formato como rm -rf .este?
Kiwy

Acepto la respuesta, aunque realmente no entiendo por qué la terminal se puede estropear de esta manera si escribo como tonto en mi teclado, nunca consigo obtener esto: D
Kiwy

Y ahora ironía ... hum
Kiwy

1
Los caracteres de control de @Kiwy no existen en su teclado, pero puede hacerlos echosalir si lo desea. Vea stackoverflow.com/questions/5947742/… para saber cómo hacerlo y termsys.demon.co.uk/vtansi.htm para obtener información sobre lo que es posible
David Wilkins,

@DavidWilkins oye, gracias, eso es bueno, hay muchas cosas que aprender y no hay tiempo para eso :-(
Kiwy

2

Supongo que esto sucede principalmente debido a caracteres no imprimibles con códigos inferiores a 0x20. Esos son códigos especiales de control / escape, que se utilizan para teclas como Retroceso, Eliminar, etc.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.