「tail -f | iconv -fsjis」は何も出力しません

「tail -f | iconv -fsjis」は何も出力しません

tail -fファイルが必要なのですが、そのコンテンツsjisはエンコードされているため、端末のネイティブ (utf-8) エンコードに変換する必要があります。

私がする時

テール -fx | iconv -fsjis

出力はありません。

テール x | iconv -fsjis

動作します。最初はバッファリングの問題だと思いましたが、試してみるunbufferstdbuf説明どおりパイプ内のバッファリングをオフにする役に立たなかった。

実際、x に 10k を超えるデータを追加しても出力は行われないので、バッファリングの問題ではないと思います (間違っていなければバッファは 4k です)。ただし、iconv は EOF を受信したときにのみ出力を開始します。

では、SJIS でエンコードされたファイルを末尾から追跡するにはどうすればよいでしょうか?

答え1

(これはあまり信じないでください) 私の記憶では、問題はlibiconv動作方法にあります。マルチバイト エンコーディングでは、デコードするためにステート マシンが必要であり、libiconv文字全体を受け取ることを好むため、1 つの関数呼び出しで文字の半分を渡して、次の関数呼び出しで残りの半分を渡すことだけはできません。

他に 2 つの解決策が考えられます。1 つは優れたアウトオブバンド方式で、もう 1 つはインバンド ハックです。

ターミナルエミュレータのエンコードを変更する(帯域外): 1 つは、ターミナル エミュレータの文字エンコードを変更することです。ネイティブ エンコードは Shift JIS です。 を確認したところkonsole、 はこれをサポートしています。メニューから、表示 → 文字エンコード → 日本語 → sjis を選択します。その後、tail -fファイルを開くだけで、 がkonsoleマルチバイト文字をデコードし、フォント グリフと一致させます。

端末エンコードをオンザフライでトランスコード(インバンド、最適)luit: は、Gilles のおかげで、かなり久しぶりにを思い出させてくれました。 を使用します。luitこれは、XOrg ディストリビューションに付属しているはずです (Debian では、パッケージ ですx11-utils)。次のように使用します。

$ luit -encoding SJIS -- tail -f x

これにより、ターミナルは SJIS をターミナル エンコーディングに、またはターミナル エンコーディングからトランスコードし、 を実行しますtail -f x。 の欠点はluit、 がサポートする豊富なエンコーディングをサポートしていないことですlibiconv。 の利点は、ほとんどどこでも利用できることです。

端末エンコードをオンザフライでトランスコード(インバンド、ハック):ttyconvこれは私が何年も前に書いたハックです(最初は C で書かれていましたが、後に Python で作り直されました) は、libiconv端末の I/O をトランスコードするために使われます。新しい疑似端末を生成し、(a) 入力した文字をローカル エンコーディングからリモート エンコーディングにトランスコードし、(b) 受信した文字をリモート エンコーディングからローカル エンコーディングにトランスコードします。私はこれを使って、標準の Linux 端末でサポートされていないエンコーディングを使用しているサーバーと通信しました。テストに使用したリモート エンコーディングはすべてシングルバイト エンコーディングだったので、Shift JIS で動作するかどうかは保証できません。最近はほとんどのシステムが Unicode に切り替わっているため、これを使う機会はあまりありません。

使い方は次のようになります:

$ ttyconv -rsjis -- tail -f x

の欠点はttyconv、私が書いたもので、私以外には誰も使っていないので、バグだらけでしょう。私はこの点で優れています。利点は を使用しているlibiconvため、エンコードが特殊である場合はこれが最善の策であることです。最後に数えたところ、ttyconv --listは 100 種類のエンコードをサポートしています。

答え2

と同様に、Rich Felker によって C 言語で書かれた もttyconvあります。tconv

見る:Re: aterm/rxvt/etc の修正の要請

関連情報