バイナリデータをUnicode端末に貼り付ける

バイナリデータをUnicode端末に貼り付ける

バイナリ データをターミナルに貼り付ける必要があります。何らかの理由で、ASCII 範囲外 ( 0x80- 0xff) のすべてのバイトが同じ 3 バイト シーケンスとして貼り付けられます0xef 0xbf 0xbd

例えば:

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

これは、端末で使用される文字エンコードと関係があります。UTF-8 から ISO 8859 などに変更すると、拡張範囲内のすべての文字が に変換されます0x3f

任意のバイナリデータをターミナルに貼り付ける方法を誰か知っていますか?

編集:これは端末に大きく依存しているようです。上記の例は Konsole でのものです。xterm では希望どおりの動作が得られましたが、Gnome Terminal では拡張範囲内の文字を貼り付けることができません。Konsole 固有の解決策があれば、ぜひ教えてください。

答え1

ef bf bdUTF-8エンコードは代替キャラクター(�) は、「値が不明または Unicode で表現できない入力文字を置き換えるために使用されます」。

あなたが説明しているのは「拡張 ASCII」ではなく、バイナリ データです。範囲内の一部のバイトは0x80ISO 0xff8859 の有効なものではないため、一部のプログラムがそれを不明な文字として扱うのは理解できます。

IBM コード ページ 850 など、255 の位置すべてを使用する 8 ビット文字エンコーディングを使用してみることもできます。

しかし、コピー元のプログラムもデータを解釈している可能性があります。ヌル バイトやターミナル エスケープ シーケンスを貼り付けるとどうなるでしょうか。このアプローチ全体が失敗する運命にあるようです。

答え2

端末は一般にバイナリ入力を受け入れるようには設計されていません。端末は制御文字がアプリケーション内で特別な意味を持つものと想定し、制御文字自体に何らかの処理(主にいくつかの信号への処理)を行います。

例外は Emacs のtermモード (またはそのバリエーションの 1 つ) で、貼り付けられたデータはアプリケーションに渡される生のテキストとして扱われます。

アプリケーションにバイナリ入力を提供する通常の方法は、ファイルまたはパイプから入力をリダイレクトすることです。データが X クリップボードにある場合は、xclipまたはを使用できますxsel

xclip -o | myapp
xsel -o | myapp

答え3

ここで期待される動作は、やくあけターミナル。実行しecho -en "\x5" | xclip、シリアル ポートが開かれた画面セッションで中ボタンをクリックしました。デバイスは予想どおりにエコーしました。

答え4

適切な回答が得られなかったコメントがいくつかあります。以下にいくつかのポイントを挙げます。

  • xterm は「任意のバイナリ データ」を受け入れません。受け入れるのは (ロケールによって異なりますが) UTF-8 または ISO-8859-1 です。後者は ICCM に準拠し、前者は XFree86 の拡張です。どちらのエンコードでも、xterm はこれらの文字を解釈して、選択範囲からのデータを提供する (試みる) 場合があります。選択範囲から UTF-8 テキストを ISO-8859-1 エンコードに貼り付けると、最も一般的に使用される文字 (線描画を含む) に近似します。

  • 選択(および貼り付け)は、ソース(選択が行われる場所)とターゲット(テキストが貼り付けられる場所)の両方に依存します。選択/貼り付けするデータの形式は両者で一致している必要があります。xterm はいくつかの形式を提供し、受け入れます(参照)。button.c情報源)。Konsole と gnome-terminal では使用する形式が少なくなります。

  • 例えば、Konsoleは後からX11の選択を行います。QClipboard::Selection方法。QtのページコメントのセクションX11 ユーザー向けの注意事項その点では興味深い読み物です。しかしコードを読むそしてそれがのみサポート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);
    }
    
  • 同様に、GNOMEのVTEはgtk_clipboard_get_for_display一般的には Qt の指示に従います。

  • IBM 850は8ビットエンコーディング(ISO-8859-1など)であり、UTF-8置換文字を表すことができません。そのため、端末は?デフォルト文字)。

参考文献:

関連情報