ゼオスTTのブログ

気が向いた時に、主にプログラミング関係の記事を書くつもり。しかし気が向かない。

GNOME端末で対話的にプログラムへバイナリを渡す

しばしば、プログラムとのやりとりの最中にバイナリを渡したい場合があるが、これが割と困る。
ということで、解決策を模索してみた。
ただし、ここでは「バイナリ」を、特殊文字*1に設定されている制御文字(例:0x03(Ctrl+C))、およびキーボードから入力できない値(0x80–0xff)*2を指すものとする。

渡す値がプログラム起動前から決まっていれば

$ perl -e 'print "\x03\xcc"' | hoge

などとすればいい話だが、プログラムの出力に合わせて柔軟に渡す値を変えようとすると、そうもいかない。

特殊文字に設定されている制御文字

まず前者は、事前にsttyコマンドで特殊文字に関する設定を変更するか、あるいはlnext(通常は Ctrl+V)でエスケープする(例:Ctrl+V → Ctrl+C)ことでなんとかなる。
これでASCIIは全てキーボードから入力できる。

キーボードから入力できない値

さて後者。
たとえキーボードから入力できなくとも、別に立ち上げた端末でクリップボードに所望の値を入れ、プログラムを起動している端末に貼り付ければ解決するに違いない。

確認してみよう。
コピーして、

$ perl -e 'print "\xcc"' | xsel -bi

貼り付けたら、

$ od -tx1
[右クリック→貼り付ける]Ì[EOF]0000000 c3 8c
0000002

ほら解決し……てない!? お前誰やねん!

……まあ、Ì のUTF-8による表現ですわな。
おそらく、文字コードの設定(UTF-8になってた)に応じて、端末が良かれと思って変換してくれたのだろう。
しかし、勝手に変換されてはたまったものではない。
そこで、端末の文字コードをISO-8859-1(いわゆるlatin1)に変更し、再度貼り付ける。

$ od -tx1
[右クリック→貼り付ける]Ì[EOF]0000000 cc
0000001

ほら解決*3

まとめ

*1:SIGINTを送信するintrとか、単語を削除するweraseとか。

*2:入力方法知ってる人いたら教えてください……。

*3:いくつかの文字コードを試してみたが、0x80–0xffの全ての値に対して変換が行われなかったのはISO-8859-1だけだった。さっすがw