Necesito poder pegar datos binarios en una terminal. Por alguna razón, cada byte fuera del rango ASCII ( 0x80
- 0xff
) se pega como la misma secuencia de tres bytes 0xef 0xbf 0xbd
.
Por ejemplo:
$ echo -en "\x80" | xclip
$ hd
<paste><EOF>
00000000 ef bf bd |...|
00000004
Tiene algo que ver con la codificación de caracteres que utiliza el terminal ya que si la cambio de UTF-8 a ISO 8859 o similar todos los caracteres del rango extendido se traducen a 0x3f
.
¿Alguien tiene una idea sobre cómo pegar datos binarios arbitrarios en la terminal?
Editar:Esto parece depender mucho del terminal. El ejemplo anterior está en Konsole. Obtengo el comportamiento deseado en xterm y Gnome Terminal no permite pegar caracteres en el rango extendido en absoluto. Aún así se agradecería cualquier solución específica de Konsole.
Respuesta1
ef bf bd
es la codificación UTF-8 dePERSONAJE DE REEMPLAZO(�), que se "utiliza para reemplazar un carácter entrante cuyo valor es desconocido o no representable en Unicode".
Lo que usted describe no es "ASCII extendido", sino datos binarios. Algunos bytes en el rango 0x80
no 0xff
son válidos para ISO 8859, por lo que es comprensible que algunos programas lo traten como un carácter desconocido.
Podría intentar utilizar una codificación de caracteres de 8 bits que utilice las 255 posiciones, como la página de códigos IBM 850.
Pero entonces el programa desde el que estás copiando podría estar interpretando los datos también. ¿Y qué sucede cuando pegas un byte nulo o una secuencia de escape de terminal? Todo este enfoque parece destinado al fracaso.
Respuesta2
Los terminales generalmente no están diseñados para aceptar entradas binarias: esperan que los caracteres de control tengan un significado especial en las aplicaciones y realizan algún procesamiento de los caracteres de control ellos mismos (principalmente en unas pocas señales).
Una excepción es el modo de Emacs term
(o una de sus variantes), que trata los datos pegados como texto sin formato que se pasa a la aplicación.
El método normal de proporcionar entrada binaria a una aplicación sería redirigir su entrada desde un archivo o canalización. Si los datos están en el portapapeles X, puedes usar xclip
o xsel
:
xclip -o | myapp
xsel -o | myapp
Respuesta3
El comportamiento esperado funcionó aquí usandoyakuakeTerminal. Lo hice echo -en "\x5" | xclip
y luego hice clic en el botón central en una sesión de pantalla con un puerto serie abierto. El dispositivo hizo eco tal como se esperaba.
Respuesta4
Hay varios comentarios que no obtuvieron una respuesta adecuada. Aquí hay algunos puntos:
xterm no acepta "datos binarios arbitrarios". Acepta (según la configuración regional) UTF-8 o ISO-8859-1. Este último sigue el ICCM, el primero es una extensión de XFree86. En cualquier codificación, xterm puede interpretar estos caracteres para (intentar) proporcionar los datos de la selección. Si pega texto UTF-8 de una selección en codificación ISO-8859-1, se aproximará a los caracteres más utilizados (incluido el dibujo de líneas).
La selección (y el pegado) dependen tanto del origen (donde se realiza la selección) como del destino (donde se pega el texto). Ambos tienen que ponerse de acuerdo sobre el formato de los datos a seleccionar/pegar. xterm proporciona y acepta varios formatos (ver
button.c
en fuentes). Konsole y gnome-terminal utilizan menos formatos.Konsole, por ejemplo, selecciona X11 como una ocurrencia tardía. Utiliza el
QClipboard::Selection
método. Comentarios de la página de Qt en la sección.Notas para usuarios de X11Es una lectura interesante en ese sentido. Perolee el códigoy ver quesoloapoyaCOMPOUND_TEXT
:if (*format == 8 && *type == ATOM(COMPOUND_TEXT)) { // convert COMPOUND_TEXT to a multibyte string XTextProperty textprop; textprop.encoding = *type; textprop.format = *format; textprop.nitems = buffer_offset; textprop.value = (unsigned char *) buffer->data(); char **list_ret = 0; int count; if (XmbTextPropertyToTextList(display, &textprop, &list_ret, &count) == Success && count && list_ret) { offset = buffer_offset = strlen(list_ret[0]); buffer->resize(offset); memcpy(buffer->data(), list_ret[0], offset); } if (list_ret) XFreeStringList(list_ret); }
Asimismo, el VTE de GNOME utilizagtk_clipboard_get_for_display, generalmente siguiendo el ejemplo de Qt.
IBM 850 tiene una codificación de 8 bits (como ISO-8859-1) y no puede representar el carácter de reemplazo UTF-8. Entonces su terminal usa
?
(elcarácter predeterminado).
Otras lecturas:
¿Por qué no puedo seleccionar/pegar en/desde otros programas?(Preguntas frecuentes sobre xterm)
El carácter predeterminado no siempre es el signo de interrogación.