最近 LC_ALL
に値を設定したことによりハマったのでメモ。
LC_ALLを設定しないほうがいい理由とLANG設定が効かない問題
システムのロケール設定は、プログラムやシステムの振る舞いに大きな影響を与えます。特に、環境変数LC_ALL
とLANG
は、その設定方法によっては期待通りの動作をしないことがあります。
ロケール設定の基礎知識
UNIX系システムでは、ロケール設定は以下の環境変数を使って行われます。
LANG
LANGUAGE
LC_CTYPE
LC_NUMERIC
LC_TIME
LC_COLLATE
LC_MONETARY
LC_MESSAGES
LC_PAPER
LC_NAME
LC_ADDRESS
LC_TELEPHONE
LC_MEASUREMENT
LC_IDENTIFICATION
LC_ALL
これらの環境変数は、文字のエンコーディング、日時の表示形式、通貨の表示形式など、システムやアプリケーションのロケールに関連するさまざまな設定を制御します。
ロケール関連の環境変数の優先順位
ロケール関連の環境変数の優先順位は、以下の通りです:
- LANGUAGE: 最も高い優先順位を持ち、主にGNU gettextによって使用されるメッセージ翻訳言語を設定します。
-
LC_ALL: 全ての
LC_*
変数を上書きします。値が設定されると、LC_*
の設定は無視されます。 -
LC_*: 特定のロケールカテゴリ(
LC_CTYPE
、LC_NUMERIC
、LC_TIME
、LC_COLLATE
、LC_MONETARY
、LC_MESSAGES
など)を設定します。 - LANG: これらの変数が設定されていない場合のデフォルト値として使用されます。
LANG
設定が効かない問題
LANG
は、デフォルトのロケール設定を指定するために使用されます。しかし、LC_ALL
が設定されている場合、LANG
の設定は無視されます。これがLANG
設定が効かない主な理由です。
具体例
例えば、以下のように環境変数を設定した場合を考えます。
export LANG=ja_JP.UTF-8
export LC_ALL=en_US.UTF-8
この場合、LANG
はja_JP.UTF-8
に設定されていますが、LC_ALL
がen_US.UTF-8
に設定されているため、LANG
の設定は無視されます。結果として、システムはすべてのロケール設定にen_US.UTF-8
を使用します。
LC_ALL
を使用しないほうがいい理由
-
デバッグが難しくなる:
LC_ALL
を設定すると、他のすべてのロケール設定が上書きされるため、特定のロケール設定がどのように機能しているのかを確認するのが難しくなります。 -
柔軟性の欠如: アプリケーションやシステムの異なる部分で異なるロケール設定を使用したい場合、
LC_ALL
を設定するとそれが不可能になります。 -
予期せぬ動作:
LC_ALL
が他のすべてのロケール設定を上書きするため、予期しない動作を引き起こす可能性があります。
まとめ
-
LC_ALL
は他のすべてのロケール設定を上書きするため、設定すると柔軟性が失われ、デバッグが難しくなります。 -
LC_ALL
が設定されていると、LANG
の設定は無視されます。 - ロケール設定を適切に行うためには、
LC_ALL
の使用を避け、必要に応じて個別のロケール設定を行う方法が良さそうです。
私は単に LC_ALL
は LC_*
を上書きするだけだと思ったのですが、LC_ALL
に値を設定してしまうと LC_*
だけでなく LANG
よりも優先された値として扱われるということでした。
正しく理解していないとハマるのでご注意ください。