Colando dados binários em um terminal Unicode

3

Eu preciso poder colar dados binários em um terminal. Por algum motivo, cada byte fora do intervalo ASCII ( 0x80 - 0xff ) é colado como a mesma sequência de três bytes 0xef 0xbf 0xbd .

Por exemplo:

$ echo -en "\x80" | xclip
$ hd
<paste><EOF>
00000000  ef bf bd                                       |...|
00000004

Tem algo a ver com a codificação de caracteres usada pelo terminal, pois se eu alterá-lo de UTF-8 para ISO 8859 ou similar, cada caractere no intervalo estendido é traduzido para 0x3f .

Alguém tem uma ideia de como colar dados binários arbitrários no terminal?

Editar: Isso parece ser muito dependente do terminal. O exemplo acima está no Konsole. Eu obtenho o comportamento desejado no xterm e o Gnome Terminal não permite colar caracteres no intervalo estendido. Qualquer solução específica do Konsole ainda seria apreciada.

    
por Job 25.06.2012 / 18:48

4 respostas

3

ef bf bd é a codificação UTF-8 de PERSONAGEM DE SUBSTITUIÇÃO ( ) , que é "usado para substituir um caractere de entrada cujo valor é desconhecido ou irrepresentável em Unicode".

O que você descreve não é "ASCII estendido", mas sim dados binários. Alguns bytes no intervalo 0x80 - 0xff não são nada ISO 8859 válido, portanto, é compreensível que alguns programas tratem isso como um caractere desconhecido.

Você pode tentar usar uma codificação de caracteres de 8 bits que use todas as 255 posições, como a página de código 850 da IBM.

Mas o programa do qual você está copiando também pode estar interpretando os dados. E o que acontece quando você cola um byte nulo ou uma seqüência de escape terminal? Toda a abordagem parece destinada a falhar.

    
por 25.06.2012 / 19:25
2

Os terminais geralmente não são projetados para aceitar entrada binária: eles esperam que os caracteres de controle tenham um significado especial em aplicativos, e fazem algum processamento de caracteres de controle (principalmente em alguns sinais).

Uma exceção é o modo term do Emacs (ou uma de suas variantes), que trata dados colados como texto bruto que é passado para o aplicativo.

O método normal de fornecer entrada binária para uma aplicação seria redirecionar sua entrada de um arquivo ou pipe. Se os dados estiverem na área de transferência X, você poderá usar xclip ou xsel :

xclip -o | myapp
xsel -o | myapp
    
por 26.06.2012 / 02:54
1

O comportamento esperado funcionou aqui usando o terminal yakuake . Eu fiz echo -en "\x5" | xclip e, em seguida, o botão do meio clicou em uma sessão de tela com uma porta serial aberta. O dispositivo ecoou exatamente como esperado.

    
por 02.12.2013 / 20:45
0

Existem vários comentários que não obtiveram uma resposta adequada. Aqui estão alguns pontos:

  • O xterm não aceita "dados binários arbitrários". Aceita (dependendo da localidade) UTF-8 ou ISO-8859-1. Este último segue o ICCM, o primeiro é uma extensão do XFree86. Em qualquer codificação, o xterm pode interpretar esses caracteres para (tentar) fornecer os dados da seleção. Se você colar texto UTF-8 de uma seleção na codificação ISO-8859-1, ele aproximará os caracteres mais usados (incluindo o desenho de linhas).

  • seleção (e colagem) depende da origem (onde a seleção é feita) e do destino (onde o texto é colado). Ambos têm que concordar com o formato dos dados para selecionar / colar. O xterm fornece e aceita vários formatos (consulte button.c in sources ). O Konsole e o gnome-terminal usam menos formatos.

  • O Konsole, por exemplo, faz a seleção do X11 como uma reflexão tardia. Ele usa o método QClipboard::Selection . Comentários da página de Qt na seção Notas para usuários do X11 é uma leitura interessante a esse respeito. Mas leia o código e veja que apenas suporta COMPOUND_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);
    }
    
  • Da mesma forma, o VTE do GNOME usa gtk_clipboard_get_for_display , geralmente seguindo o exemplo de Qt.

  • O IBM 850 é uma codificação de 8 bits (como o ISO-8859-1) e não pode representar o caractere de substituição do UTF-8. Portanto, seu terminal usa ? (o caractere padrão ).

Leitura adicional:

por 05.11.2016 / 21:12