2016/10/18 20:09:23

Linuxのlocaleについてちょっとした知識

目次(クリックするとジャンプします)
  • 1:localeってなんだっけ
  • 2:localeを構成する仕組み
  • 2.1:localeを構成するファイルやプログラミング
  • 2.2:localeを有効にするには
  • 3:ちょっと localeのソースファイルをのぞいてみる
  • 3.1:文字の定義はどんな感じ?
  • 3.2:などのコードはなにを示している?
  • 3.3:文字の文字コードとの対応
  • 3.4:日付形式はどんなふうになっているの?
  • 4:まとめ

localeってなんだっけ

最近ArchLinuxを使うべくいろいろ勉強しています。

その一環としてあまり気にしていなかったlocaleについて調べてみました。

localeは国や地域などの言葉・文字・単位・日付形式などを定義したものです。このlocaleを切り替えることでLinuxは国際化ができるようになっています。

ちなみに国際化はinternationalizationまたはinternationalisationで、単語としては長すぎるのでi18nと略されます。iとnの間に18文字あるからなんですね。

@MINOはいままであんまり考えなしに、en_USja_JPを有効にしていましたが、そもそもlocaleとはどんな風に定義されているの気になりますよね(よね?)

localeを構成する仕組み

localeは仕組みとして、以下のようなファイルやプログラムから生成されます。

コンパイルされてオブジェクトを使うようになっているんですね。

localeを構成するファイルやプログラミング

localeのリスト /etc/locale.gen
localeをコンパイルするコマンド /usr/bin/localedef
localedefを使いやすくするシェルスクリプト /usr/bin/locale-gen
localeのソースファイル /usr/share/i18n/locales/
localeで使用される文字コードにUCS変換対応表 /usr/share/i18n/charmaps
コンパイルされたlocaleオブジェクトファイル(実体) /usr/lib/locale/locale-archive
localeのコンフィグ /etc/locale.conf

localeを有効にするには

一応localeの設定の方法を簡単に整理しておきましょう。

  • locale.defで有効にしたいlocaleをアンコメントする
  • localedefでlocaleをコンパイルする
  • もしくはlocale-genがあれば locale-genでコンパイルする
  • システムのlocaleの設定はlocale.confを適切に設定する
  • ユーザー単位は.bashrcにlocaleを設定する

ちょっと localeのソースファイルをのぞいてみる

日本のlocaleソースファイルを見てみます。以下にあるかと思います(Ubuntu/debian,Arch)

/usr/share/i18n/locales/ja_JP

文字の定義はどんな感じ?

このファイルにはいろいろ定義されていますが、とりあえず文字の定義を見てみましょう。

37行あたりにLC_CTYPEという項目があると思います。そこが文字の定義になっています。

jhiraとかjkataとかいう項目があるかとおもいますが、それぞれひらがな・カタカナの定義です。

日本語では数字・記号・ひらがな・カタカナ・漢字・アルファベット(ローマ字)を使います。

それぞれの文字にはコードセット内でコードが決められているので、localeでは使うコードの定義を行っています。

そのコードがなどと記述されています。

英語だと文字数が少ないですが、ひらがな・カタカナはともかく漢字がしこたまあるので、これを定義しているコードもしこたまあります。

実際ja_Jpjkanjiの項目にしこたま漢字のコードが記述されているので相当長いです。

ja_JPは15000行程度ありますが、en_USは200行に届きません。

そのためロケールアーカイブファイルはそのlocaleによって容量がかなり違いマス。

ロケールアーカイブファイルのなどのコードはなにを示している?

これらのコードはUCS(Universal Multiple-Octet Coded Character Set) のコードです。

Unicodeと互換性があるそうなのでUnicodeといってもいいのかもしれません。

UCS4byteにて文字を管理する文字集合(UCS-4とよばれます)です。約21億文字の表現が可能です。すごい大きいです。

世の中に21億文字もユニークな文字が存在しているかどうかはわかりませんが、とにかく文字という文字はこのUCSで体系コードとして整理できます。

いろいろな文字コードが存在しますが、このUCSは事実上、地球に存在する(現在使われている)文字がすべてインデックスできるので、このUCSのコードを使うと、アルファベットだろうが漢字だろうが記号だろうが、一意に文字を特定できます。

世の中には様々な文字コードが存在しますし、互換性がないものもたくさんあります。

そこでLinuxのlocale定義は、UCSのコードを使い、別途charmapというUCSコードから目的の文字コードに変換させるための対応リストを用意しています。

これで日本用のlocale(ja_JP)に対して、EUC-JPとか、Shift-JISとか、UTF-8などを選択できるようになっています。

文字の文字コードとの対応

例えば日本語のひらがなの大文字の「あ」はUCS

U3042

となります。

これに対し、EUC-JPでは

a4 a1

UTF-8では

e3 82 a1

となり、EUC-JPUTF-8では文字コードが全然違うことがわかります。

UCSコードからの文字コード変換の対応表は各文字コードごとに以下のディレクトリにあります。

/usr/share/i18n/charmaps

例えばEUC-JP用の対応表は以下の名前でおかれています。

EUC-JP.gz

これをエディタなどで開けてみて <U3042> の欄を確認してみると以下のような記述になっています。

<U3042> /xa4/xa2  HIRAGANA  LETTER  A

xは16進数を表すプレフィックスです。

<U3042>EUC-JPではa4a2ってコードだよー」と定義してることがわかりますね。

一方UTF-8は同じディレクトリに

UTF-8.gz

として置かれています。

こちらも の欄を確認してみると以下のような記述になっています。

<U3042>  /xe3/x82/xa1  HIRAGANA  LETTER  A

ちゃんと対応していますね。

こうしてlocaledefを実行した場合に、これらの文字コード対応表が使われ、UCSコードから目的の文字コードのコードに変換され、各文字コードを対応付けることができているのデス。

日付形式はどんなふうになっているの?

もうちょっと見てみましょう。日本では日付を曜日で表したりしますので、この曜日が定義されている必要がありますよね。他にも月や日は漢字ですのでこれらの使い方も定義されているはずです。

日付はLC_TIMEとして定義されています。 ja_JPのファイルではかなり下の方に定義があります(たぶん14913行あたり)。

さてこの定義にaddayといういかにも日付っぽい定義があるかと思います。そこには以下のようなコードが記述されているかと思います(;とか”とかは外しています)。

<U65E5> <U6768> <U706B> <U6C34> <U6728> <U91D1> <U571F>

これらはどんな文字に対応するのでしょうか?確認してみました。

コードの確認はwikipediaにUnicode一覧があるのでそれを使うといいかと思います。

Unicode一覧表

それぞれ表を見てみると

日 月 火 水 木 金 土

に対応しているのがわかるかと思います。

addayの下にdayという定義もありますが、これも簡単ですね。

日曜日 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日

に対応しています。3文字でもちゃんと定義されているんですね。

他にも単位・住所の書き方・はいいいえの形式・会社組織の表記形式などなどさまざまな定義がされています。

どんな定義がされているかは、licale(5)のmanを確認してもらえたらと思います。

まとめ

最初からlocaleのオブジェクトファイルを用意していないのは、文字コードとloclaeのセットに選択の余地があるからなんだと思います。

日本語だけでも結構な数の文字コードがありますし、全部の文字コードとlocaleの組み合わせのオブジェクトファイルを用意したらかなりの分量になりそうですよね。

ですから使う分だけオブジェクトファイルを作って有効にするという方法になっているのかなと思います。