環境変数によるロケールの管理

Linuxは世界中の数十にも及ぶ言語で使われている。Linuxのソースコードはフリーかつオープンなので、たとえ大企業が少数言語の利用者向け市場を価値あるものと認めなかったとしても、少数言語の話者は自分たちの言語サポートを追加することができる。複数の言語、または英語以外の言語を使う場合は、各種言語をサポートするためにLinuxがロケールをどのように用いるのかを知っておく必要がある。実際、ロケールを理解しておくことは、英語しか使わない場合でも役に立つことがある。

ロケールの選択は、環境変数の設定によって行う。各種の環境変数によってさまざまな設定が行える。LC_MESSAGESは、言語と、メッセージのエンコーディングを指定する。また、GUIコンポーネントがGNUのgettextまたはその類のものを使って翻訳結果を取得する場合は、そのラベルに対するエンコーディングもLC_MESSAGESによって決まる。なお、わずかではあるが、ほかの方法で翻訳結果を取得するプログラムや、LC_MESSAGESの影響を受けないプログラムも存在する。

LC_CTYPEは文字クラスを定義する。文字クラスとは、さまざまなプログラム、特に正規表現のマッチャが用いる名前付きの文字セットである。grepなど、[:alnum:]のような文字クラスを使用するプログラムでは、ロケールによってクラスのメンバーシップが変わる。書き込みシステムが大文字と小文字を区別する場合、LC_CTYPEによって両者の関係が決まる。

ソート順序の制御はLC_COLLATEによって行う。同一の書き込みシステムであっても、ソート順序は変えることができる。ASCII順序では、A B C … a b c….というように、大文字のグループが小文字のグループよりも順序が前になる。フランス語の順序では、a A b B c C….というように、各小文字のすぐ後に同じアルファベットの大文字が位置する。A a B b C c….のように、各大文字のすぐ後に同じアルファベットの小文字が位置するロケールもある。

ソート順序は、ソート処理だけでなく、正規表現における文字範囲にも影響する。ASCII順序では、[A-Z]という表現に含まれるのは、アルファベットの大文字26文字である。この正規表現がAで始まりZで終わるアルファベットを表しているからだ。ASCII順序では、アルファベットの大文字がAからZまで連続して1つのブロックを形成している。しかし、フランス語のロケールでは、Aで始まりZで終わるアルファベットの集合には、小文字のaを除くすべてのアルファベットが含まれる。

日付および時刻の書式はLC_TIMEによって制御される。アメリカ英語では、dateコマンドの結果が次のように表示される。

Fri Apr 14 20:33:28 PDT 2006

カタロニア語では、次のように、言葉は違うが書式は同じだ。

dv abr 14 20:33:49 PDT 2006

しかし、日本語では、最初が年、その後に月、日、曜日が続き、最後に時刻が表示される。

2006年 4月 14日 金曜日 20:34:42 PDT

数値の書式を決定するのはLC_NUMERICである。アメリカ英語では、ピリオドが小数点、コンマが整数部の3桁ごとの区切りになる。

652,314,159.278

ドイツ語では、区切り方は同じだが、ピリオドとコンマの意味が逆になる。

652.314.159,278

ヒンディー語では、ピリオドおよびコンマの働きはアメリカ英語と同じだが、百の位以下が3桁の区切りになるのに対し、それより上の整数部は2桁ずつ区切られる点が異なる。

65,23,14,159.278

通貨の書式はLC_MONETARYによって制御される。この環境変数は、金額の書式に加え、通貨単位の記号や、負の値の表記法なども決まる。

そのほかに次のような環境変数がある。

  • LC_PAPER:用紙サイズ
  • LC_NAME:個人名の書式
  • LC_ADDRESS:住所の書式
  • LC_TELEPHONE:電話番号の書式
  • LC_MEASUREMENT:測定法の単位

環境変数の階層

ほとんどの場合、これらの環境変数のすべてに同じ値を設定することになるが、別の値を設定することに意味がある場合もある。たとえば、インターフェイス言語は英語だが、フランス語のデータをソートしたい場合は、LC_MESSAGESをen_USに、LC_COLLATEをfr_FRにするとよい。

すべてに同じ値を用いる場合は、すべての環境変数を個別に設定する必要はない。この場合はLC_ALLまたはLANGを設定するだけでよい。プログラムは、こうした環境変数を参照して使用すべきロケールを判断する。その手順は次のとおりだ。

  1. 環境変数LC_ALLが定義済かつnullでない場合、LC_ALLの値が使用される。
  2. コンポーネント特有の適切な環境変数 ― たとえば、LC_COLLATE ― が設定済かつnullでない場合、その値が使用される。
  3. 環境変数LANGが定義済かつnullでない場合、LANGの値が使用される。
  4. 環境変数LANGが未設定またはnullの場合、実装に依存したデフォルトのロケールが使用される。

ただし、目的別に異なるロケールを使用する場合はLC_ALLの設定を解除する必要があることにご注意いただきたい。

もう1つ、LANGUAGEという環境変数があるが、この変数を使用するのは、多くのプログラム向けにメッセージの翻訳結果を提供する仕組み、GNU gettextだけである。ほかの変数とは異なり、この環境変数では複数のロケールをコロンで区切って指定できる。これらのロケールは、メッセージカタログが見つかるものが現れるまで順に試される。たとえば、sv_SE:nn_NO:de_DEという指定は、ユーザはスウェーデン語を使いたいのだが、スウェーデン語が利用できない場合はノルウェー語を、ノルウェー語も利用できない場合はドイツ語を用いることを示す。LANGUAGEが定義されている場合、その値は、LC_ALL、LC_MESSAGES、LANGの設定値よりも優先される。

ロケール名

ロケール名は次の形式で表現される。

language(_territory)(.encoding)(@modifier)

必須になるのは言語(language)コードだけで、たとえば、英語を表す言語コードはenfr_FRはフランスにおけるフランス語、fr_CAはカナダにおけるフランス語、en_CAはカナダにおける英語、といった具合である。エンコーディング(encoding)の指定も可能である。英語の場合、ASCIIがデフォルトのエンコーディングになっているが、en_US.UTF-8と指定すればUTF-8エンコーディングによるアメリカ英語になる。通常、言語コードはISO-639-1に定義された2文字のコードの一覧から選択し、国/地域コードはISO-3166-1に定義された2文字のコードから選択する。

修飾子(modifier)としてもっともよく見かけるのはeuroである。この修飾子は、EUにユーロが導入される前にロケール定義が作られた国のロケールでユーロ通貨を用いる場合に使用される。たとえば、es_ES@euroは現在のスペインのロケールであり、es_ESは同じくスペインのユーロ導入前のロケールである。

こうした名前付け規則に従わない特別なロケールもいくつか存在する。Cロケールとしてもよく知られているPOSIXロケールは、伝統的なUNIX環境を設定するもので、ASCIIエンコーディング、POSIX文字クラス、アメリカ英語の日時、数、通貨の書式を用いる。sortやgrepのようなプログラムの使用時にうまく動作しない場合は、いつもと異なるソート順序や文字クラスを指定したロケールを使っていることが原因かもしれない。ロケールをPOSIXにすれば、適切な設定になるはずである。

現在のロケールを調べるには、localeコマンドを引数を与えずに実行する。LANGUAGEを除き、関連する環境変数の値がすべて表示される。また、locale charmapとすると現在のエンコーディング名が表示される。利用可能なロケールを調べるには、locale -aを実行する。利用可能なエンコーディングを調べるには、locale -mとすればよい。

ロケールのインストール

必要なロケールがコンピュータにインストールされていないこともある。その場合は、自分でインストールすることができる。ロケール定義は、locale(5)manページに記された特別な書式に従うASCII形式のプレーンテキストファイルとして保存される。独自のロケール定義を書く方法の説明はほかの記事に譲るが、ディストリビューションのglibcディレクトリ内のlocaledata/localesを探せば多数のロケール定義ファイルが見つかるだろう。ロケール定義ファイルの名前はロケール名と同じで、南アフリカ共和国のズールー語であればzu_ZAとなる。

ロケールファイルのインストールには、localedefを使用する。ズールー語をインストールする場合のコマンドは次のとおり。

localedef -i zu_ZA -f ../charmaps/UTF-8 zu_ZA

最後の引数はロケール名である。ロケール定義ファイル名は、-iフラグの後に指定する。-fフラグの後には適切な文字セット定義ファイル、多くの場合はUTF-8、を指定する。

今後の展望

2文字のコードでは多数の言語を表現しきれないため、ISO-639-2では3文字のコードも使用されている。同様に、ISO-3166-2に定義された国コードにも3文字のコードが現れている。

もう1つの進展として、Unicode Consortiumが後援するCommon Locale Data Repository(CLDR)プロジェクトがある。オペレーティングシステムおよび開発者ごとに別々の書式でローカライズ情報の編集や保存を行うのは非効率的だとして、このCLDRプロジェクトでは、既にJavaなどのプログラムで使用されているロケール情報を格納するためのXMLベースの新しいクロスプラットフォームな仕組みを開発中である。

原文