最近 LC_ALL に値を設定したことによりハマったのでメモ。
LC_ALLを設定しないほうがいい理由とLANG設定が効かない問題
システムのロケール設定は、プログラムやシステムの振る舞いに大きな影響を与えます。特に、環境変数LC_ALLとLANGは、その設定方法によっては期待通りの動作をしないことがあります。
ロケール設定の基礎知識
UNIX系システムでは、ロケール設定は以下の環境変数を使って行われます。
LANGLANGUAGELC_CTYPELC_NUMERICLC_TIMELC_COLLATELC_MONETARYLC_MESSAGESLC_PAPERLC_NAMELC_ADDRESSLC_TELEPHONELC_MEASUREMENTLC_IDENTIFICATIONLC_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 よりも優先された値として扱われるということでした。
正しく理解していないとハマるのでご注意ください。