¿Cómo leer una entrada de 4k sin nuevas líneas en un terminal?

Pregunta:

Entonces tengo muchos datos SIN NUEVAS LÍNEAS en el portapapeles (es un archivo SVG grande en una línea). Yo fuí

$ cat >file.svg

luego intenté pegar (en Gnome Terminal), pero solo se aceptaron los primeros 4kB caracteres.

Supongo que esta es una característica / limitación de readline.

¿Hay alguna forma de leer desde STDIN que evite este problema?

EDITAR

Caso de prueba: cree un archivo de demostración. Este tendrá ~ 4k "=" símbolos seguidos de "foo bar".

{ printf '=%.0s' {1..4095} ; echo "foo bar" ; } > test.in

Copia eso en tu portapapeles

xclip test.in

(si desea hacer clic con el botón central para insertar) o

xclip -selection clipboard test.in

(si desea usar Ctrl-Shift-Insert para pegarlo)

Luego cat >test.out , pegue (de cualquier manera). Presione Ctrl-D para finalizar la transmisión. cat test.out – ¿ves "foo bar"?

En mi configuración (Ubuntu 12.04, Gnome Terminal, zsh) cuando pego, solo veo el = y no veo la foo bar . Lo mismo cuando inspecciono test.out .

Respuesta:

Si entiendo la fuente correctamente, bajo Linux, la cantidad máxima de caracteres que se pueden leer de una vez en un terminal está determinada por N_TTY_BUF_SIZE en la fuente del kernel. El valor es 4096.

Esta es una limitación de la interfaz de la terminal, específicamente el modo canónico ("cocinado") que proporciona un editor de línea extremadamente tosco (retroceso, enter, Ctrl + D al comienzo de una línea para el final del archivo). Ocurre completamente fuera del proceso que está leyendo.

Puede cambiar el terminal al modo sin procesar, lo que deshabilita el procesamiento de línea. También deshabilita Ctrl + D y otras sutilezas, poniendo una carga adicional en su programa.

Esta es una antigua limitación de Unix que nunca se ha solucionado porque hay poca motivación. Los humanos no entran en filas tan largas. Si estuviera alimentando la entrada de un programa, redirigiría la entrada de su programa desde un archivo o una tubería.

Por ejemplo, para usar el contenido del portapapeles X, xsel desde xsel o xclip . En tu caso:

xsel -b >file.svg
xclip -selection clipboard >file.svg

Quite -b o -selection clipboard para usar la selección X (la que se establece al resaltar con el mouse) en lugar del portapapeles.

En OSX, use pbpaste para pegar el contenido del portapapeles (y pbcopy para configurarlo).

Puede acceder al portapapeles X a través de SSH si activa el reenvío X11 con ssh -X (que algunos servidores pueden prohibir). Si solo puede usar ssh sin el reenvío de X11, puede usar scp , sftp o sshfs para copiar un archivo.

Si pegar es la única solución porque no puede reenviar el portapapeles o no está pegando pero, por ejemplo, simulando escribir en una máquina virtual, un enfoque alternativo es codificar los datos en algo que tenga nuevas líneas. Base64 es muy adecuado para esto: transforma datos arbitrarios en caracteres imprimibles e ignora los espacios en blanco al decodificar. Este enfoque tiene la ventaja adicional de que admite datos arbitrarios en la entrada, incluso caracteres de control que el terminal interpretaría al pegar. En su caso, puede codificar el contenido:

xsel -b | base64 | xsel -b

luego decodifícalo:

base64 -d
Paste
Ctrl+D

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top

web tasarım