端末に対する$ LANGの影響


11

私は変数がgnome-terminal(およびその文字エンコーディング設定オプション)でどのように動作するかを学習しようとしてい$LANGます。私は主な文字セットとしてiso8859-1(latin1)を使用しており、すべてのファイル名はそのようにエンコードされています。

次のテストではls -l、ファイル名にスペイン語のアクセント付き文字を含むディレクトリを実行します。

ケース#1:

  • ISO-8859-1用に構成されたgnome-terminal
  • LANG 「en_US-iso8859-1」に設定
  • 結果:すべてのファイルが正しく表示されます

ケース#2:

  • UTF-8用に構成されたgnome-terminal
  • LANG 「en_US-iso8859-1」に設定
  • 結果:スペイン語の文字すべてに文字化けが表示されます。端末の文字エンコーディングを変更したため、これは予想された

ケース#3:

  • ISO-8859-1用に構成されたgnome-terminal
  • LANG 「en_US-UTF-8」に設定
  • 結果:スペイン語の文字すべてに文字化けが表示されます。

この最後のケースで文字化けした文字が表示されるのはなぜですか?lsの出力は、ファイル名をそのままgnome-terminalに直接送信すべきではありませんか?そして、gnome-terminalはISO-8859-1用に構成されているので、私はそれらが正しく見えると期待していました。

一瞬、多分、おそらくbashは私の$LANG変数を考慮し、いくつかの変換を実行していると思いました。次に、端末をUTF-8に切り替えましたが、文字が正しく表示されません。私はlsの出力をxxdにパイプしましたが、驚いたことに、ISO-8859-1というファイルがエンコードされているのがわかります。

まとめ:リストにISO-8859-1文字が含まれていて、ターミナルエミュレーターが同じ文字エンコード用に構成されている場合:LANG他に設定されている場合、誰が変換を行っていますか?

あなたが提供できる助けをありがとう。

クラコニア

回答:


5

の設定はLANG、端末の設定と一致する必要があります。より正確には、LC_CTYPE(文字エンコーディング)の設定は端末のエンコーディングと一致する必要があり、他のロケール設定は一致する必要はありません。また、端末のエンコーディングは通常、ロケール変数ではなく、端末エミュレータのオプションによって指定されます。はLC_CTYPE、2つの指示を組み合わせます。それは、アプリケーションで端末で使用するエンコーディング(入力と出力の両方)を通知し、ファイルで使用するエンコーディングをアプリケーションに通知します。ケース2と3では、ls出力を端末とは異なるエンコーディングで表示するように指示しているため、出力が文字化けします。

UTF-8エンコードとlatin-1エンコードの両方を別々に使用する場合は、UTF-8を使用するように端末を構成してください。これにより、LC_CTYPEUTF-8を示す値に設定されます。この設定を上書きしないでください。(ターミナルエミュレータがを設定しない場合はLC_CTYPE、シェルのスタートアップファイルまたはセッション全体でオーバーライドしてください。)UTF-8ターミナルでlatin-1データを操作するluitには、(Xユーティリティスイートに含まれている)を使用します。

LC_CTYPE=en_US.iso88591 luit

(たとえば、同じエンコーディングの他のロケールを使用できますLC_CTYPE=es_ES.iso88591 luit。)


その素晴らしい説明、特にLC_CTYPEの2つの表示を説明してくれたGillesに感謝します。
クラコニア2012

最後のケースに戻る:すべてのファイル名がlatin1でエンコードされていることに加えて、最終出力デバイスであるグリフ(端末)を作成するデバイスもlatin1用に構成されているため、ファイルが正しく表示されると期待していました。 (LC_CTYPEに関係なく)...
クラコニア2012

lsLC_CTYPE(この場合はUTF-8に設定)を考慮して、ある種の文字セット検証を実行することは、私には思いもよらないことでした。 ")。Luitのように「変換」を実行しないため、「検証」と言いました。こんな感じですか?
クラコニア2012

@Craconia 3番目のケースでlsは、印刷できない文字をに置き換え?ます。ラテン語1でエンコードされた実際の単語を表すほとんどの文字列は、UTF-8として解釈すると印刷できない文字になります。
Gilles「SO-邪悪なことをやめよ」

5

#2と#3のケースでは、2つの異なるエンコーディングUTF-8とLatin-1を混在させています。ケース1では、両方にLatin-1を使用しているので、問題はありません。

lsコマンド(および他のすべてのウェルに動作とプログラム)を決定するためのLANG設定を使用して符号化を

2つの異なる言語を混在させることができますが、2 つの異なるエンコーディングを混在させることはできません

LC_ *環境変数もLANG変数と同じエンコーディングを使用していることを確認してください。

経験則として、最近はシステムをUTF-8のみを使用するように構成する必要があります。

古い形式のデータファイル(Javaプロパティなど)を編集する必要がある場合は、専用のエディタ(Java IDEなど)を使用するか、iconvまたは `recode ..


ありがとう。はい、近い将来UTF-8に切り替える予定です。たくさんのファイル名とたくさんのテキストファイルを変換しました。iconv&convmv to the rescue ...
クラコニア

0

これはあなたのニーズの範囲外かもしれませんが、...

それはRHEL5で判明し、おそらく以前は、いくつかのgdの予見された理由により、多くのmanページが何らかの形でascii化されています。つまり、未加工のmanページがネイティブの文字セットから7ビットASCIIに変換されています。LCとLANGをどのように使用しても、のmanページlatin1は効果的に役に立たないmanページを生成します。内のすべての特殊(8ビット)文字は、7ビットのプレースホルダー(通常は??)に置き換えられました。私はこれを陽気だと思います。

ただし、utf8これらのマニュアルページのバージョンは、言語固有のディレクトリに存在する場合があります。トリックは、正しい名前でそれらを求めることです。たとえば、latin1は実際にはiso_8859-1です。その上でmanページを実行し、LANG設定が正しい場合は、期待どおりの結果が得られます。マニュアルページは、言語固有のサブディレクトリ(en/man7/iso_8859-1.7)にあります。しかしiso-8859-1、何らかの理由でを要求すると、ASCIIバージョンが表示されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.