107.3 レッスン 1
Certificate: |
LPIC-1 |
---|---|
Version: |
5.0 |
Topic: |
107 管理タスク |
Objective: |
107.3 ローカリゼーションと国際化 |
Lesson: |
1 of 1 |
はじめに
すべての主要なLinuxディストリビューションは、国際化の機能設定をカスタマイズできます。例えば、タイムゾーンや文字エンコーディングなど、地域や言語に関する設定を、オペレーティングシステムのインストール中や、インストール後に変更できます。
それぞれのアプリケーションは、システムの設定ファイルやコマンドと環境変数を利用して、使用する言語や時刻を決定します。そのため、ほとんどのLinuxディストリビューションにおいて、時間や言語などのローカリゼーション設定を調整する方法が標準化されています。これらを調整することは、ユーザーエクスペリエンスを向上させるだけでなく、システムイベント(たとえばセキュリティ問題の報告)のタイミングを正しく決定するためにも重要です。
現代的なオペレーティングシステムは(母国語だけではない)さまざまな文字を取り扱うための 文字エンコーディング規格 を必要としており、Linuxも例外ではありません。コンピュータは数値しか扱えないので、文字というのは図形記号に対応付けられた数値(コード)にすぎません。コンピュータープラットフォームが異なると文字に割り当てる数値が異なることがありますから、互換性を持たせるためには同じ文字エンコード規格を使う必要があります。あるシステムで作成したテキストドキュメントを別のシステムで読み取るには、文字セット(訳注: 文字とそのコード番号の対応付けを定める規格。符号化文字集合)とエンコード形式(訳注: 文字コードの並びをどのように表現するかを定める規格。文字符号化方式)の両方を揃えるか、少なくとも相互の変換方法を知っている必要があります。(訳注: 文字セットとエンコード形式は本来独立した概念ですが、併せて1つの規格としてまとめられることが少なくありません。日本では単に「文字コード」とか「エンコード」と呼ばれることが多いですが、本章では両者を併せて「文字エンコード規格」と表記しています)。
Linuxベースのシステムのローカリゼーション設定は統一されておらず、ディストリビューション間に微妙な違いがあります。とはいえ、すべてのディストリビューションは、システムを国際化するための同じ概念と基本的な設定ツールを使っています。
タイムゾーン
タイムゾーンは、1時間に相当するくさび(訳注: リンゴのくし切りを思い出してください)で地球の全表面を区切ったものです。つまり、同じ時刻にあるとみなす地域です。1日の始まりは経度によって異なるので、経度0である 子午線 を基準にしており、そこでの時刻を UTC(Coordinated Universal Time/協定世界時) と呼びます。タイムゾーンの自然な区切りは(15度おきの)経度線になりますが、実用上の理由から、国や州・県などの境界にあわせて人為的に調整されています。
行政区画との関連性が高いため、タイムゾーンの名前は通常、そのゾーン内の大国や大都市など、地域内の主要な地理的目標物にちなんで付けられます。また、あるタイムゾーンを示すために、UTCを基準にした時差を使うこともあります。たとえば、タイムゾーン GMT-5 は、UTC時刻より5時間遅れている時刻の地域を示します。同様に、タイムゾーン GMT+3 はUTC時間より3時間進んでいる時刻の地域を示します。GMT(グリニッジ標準時)という用語(Greenwich Mean Time)は、時差に基づくゾーン名表記においてUTCの同義語として使用されます。(訳注: 日本時間(JST)は GMT+9 になり、GMTよりも9時間進んでいる(早い)タイムゾーンにあたります。)
ネットワークに接続したマシンには世界のさまざまな場所からアクセスできるため、ハードウェアクロックをUTC(GMT+0タイムゾーン)に設定し、使用場所に応じてタイムゾーンを選択するのがお勧めです。たとえば、クライアントや他のサーバーとの間で時刻が異なることを避けるために、クラウドサービスではUTCを使用するのが一般的です。対して、サーバーに対してリモートセッションを開くユーザーは、自分のローカルタイムゾーンを使用するのがお勧めです。状況に応じてそれぞれにふさわしいタイムゾーンを扱うことことは、オペレーティングシステムの働きです。
コマンド date
は、日付と時刻に加えて、タイムゾーンも出力します。
$ date Mon Oct 21 10:45:21 -03 2019
値 -03
がUTCからの時差を示していて、表示された時刻がUTCより3時間遅れていることを意味します。つまり、ローカルのタイムゾーンは GMT-3 になります(訳注: 南米の一部やグリーンランドが該当します)。systemdを使用するディストリビューションで timedatectl
を使うと、システムの時刻と日付に関する詳細を表示します。
$ timedatectl Local time: Sat 2019-10-19 17:53:18 -03 Universal time: Sat 2019-10-19 20:53:18 UTC RTC time: Sat 2019-10-19 20:53:18 Time zone: America/Sao_Paulo (-03, -0300) System clock synchronized: yes systemd-timesyncd.service active: yes RTC in local TZ: no
Time zone
エントリには、地域名に基づくタイムゾーン名(America/Sao_Paulo
など)が示されることもあります。システムのデフォルトタイムゾーンは、/etc/timezone
ファイルに地域に基づくゾーン名、ないしは時差オフセットのいずれかを記入することで決定されます。UTCからの時差オフセットでタイムゾーン名を指定する場合には、名前の前に Etc
を付加します。つまり、デフォルトのタイムゾーンをGMT+3に設定するには、タイムゾーンの名前を Etc/GMT+3
と指定します。
$ cat /etc/timezone Etc/GMT+3
地域に基づくタイムゾーン名を使えば時差を知っている必要はありませんが、正しいタイムゾーン名を選択するのはそれほど簡単ではありません。1つのタイムゾーンに複数の名前があることが多いため、時差を覚えにくいのです。tzselect
コマンドを使うと対話的に正しいタイムゾーンを定義できるので、迷うことが少なくなります。tzselect
は、GNU Cライブラリに関連する重要なコマンドと同じパッケージに含まれるので、ほぼすべてのLinuxディストリビューションで使用できるはずです。(訳注: タイムゾーンは
tzselect
コマンドは、たとえば “Brazil” の “São Paulo City” のタイムゾーンを指定する場合など便利です。tzselect
は、対象の大まかな地域を尋ねることから始めます。
$ tzselect Please identify a location so that time zone rules can be set correctly. Please select a continent, ocean, "coord", or "TZ". 1) Africa 2) Americas 3) Antarctica 4) Asia 5) Atlantic Ocean 6) Australia 7) Europe 8) Indian Ocean 9) Pacific Ocean 10) coord - I want to use geographical coordinates. 11) TZ - I want to specify the time zone using the Posix TZ format. #? 2
オプション 2
は南北アメリカを示し、複数のタイムゾーンを含みます。緯度経度(オプション 10
)や時差表記(Posix TZ形式 とも呼ばれます/オブション 12
)を使用してタイムゾーンを指定することもできます。(地域を指定した場合)次のステップは国を選択することです:
Please select a country whose clocks agree with yours. 1) Anguilla 19) Dominican Republic 37) Peru 2) Antigua & Barbuda 20) Ecuador 38) Puerto Rico 3) Argentina 21) El Salvador 39) St Barthelemy 4) Aruba 22) French Guiana 40) St Kitts & Nevis 5) Bahamas 23) Greenland 41) St Lucia 6) Barbados 24) Grenada 42) St Maarten (Dutch) 7) Belize 25) Guadeloupe 43) St Martin (French) 8) Bolivia 26) Guatemala 44) St Pierre & Miquelon 9) Brazil 27) Guyana 45) St Vincent 10) Canada 28) Haiti 46) Suriname 11) Caribbean NL 29) Honduras 47) Trinidad & Tobago 12) Cayman Islands 30) Jamaica 48) Turks & Caicos Is 13) Chile 31) Martinique 49) United States 14) Colombia 32) Mexico 50) Uruguay 15) Costa Rica 33) Montserrat 51) Venezuela 16) Cuba 34) Nicaragua 52) Virgin Islands (UK) 17) Curaçao 35) Panama 53) Virgin Islands (US) 18) Dominica 36) Paraguay #? 9
ブラジル国内には4つのタイムゾーンがあるので、国だけではタイムゾーンが決まりません。次のステップで、tzselect
は国内の地域を要求します:
Please select one of the following time zone regions. 1) Atlantic islands 2) Pará (east); Amapá 3) Brazil (northeast: MA, PI, CE, RN, PB) 4) Pernambuco 5) Tocantins 6) Alagoas, Sergipe 7) Bahia 8) Brazil (southeast: GO, DF, MG, ES, RJ, SP, PR, SC, RS) 9) Mato Grosso do Sul 10) Mato Grosso 11) Pará (west) 12) Rondônia 13) Roraima 14) Amazonas (east) 15) Amazonas (west) 16) Acre #? 8
すべての地域名が利用できるわけではありませんが、最も近い地域を選択すれば十分です。tzselect
は、指定された情報から対応するタイムゾーンを表示します。
The following information has been given: Brazil Brazil (southeast: GO, DF, MG, ES, RJ, SP, PR, SC, RS) Therefore TZ='America/Sao_Paulo' will be used. Selected time is now: sex out 18 18:47:07 -03 2019. Universal Time is now: sex out 18 21:47:07 UTC 2019. Is the above information OK? 1) Yes 2) No #? 1 You can make this change permanent for yourself by appending the line TZ='America/Sao_Paulo'; export TZ to the file '.profile' in your home directory; then log out and log in again. Here is that TZ value again, this time on standard output so that you can use the /usr/bin/tzselect command in shell scripts: America/Sao_Paulo
結果のタイムゾーン名 America/Sao_Paulo
を /etc/timezone
に書き込めば、システムのデフォルトタイムゾーンを設定できます。
(訳注: 日本では Asia
- Japan
を指定すると、Asia/Tokyo
が表示されます。)
$ cat /etc/timezone America/Sao_Paulo
tzselect
の出力にも示されますが、システムのデフォルトのタイムゾーンにかかわらず、環境変数 TZ
がシェルセッションのタイムゾーンを定義します。行 TZ='America/Sao_Paulo'; export TZ
をファイル ~/.profile
に記入して、TZ
環境変数をエクスポートすると、 America/Sao_Paulo
が以後のセッションのタイムゾーンになります。異なるタイムゾーンの時刻を表示するために、現在のセッション中に TZ
環境変数を一時的に変更することもできます。
$ env TZ='Africa/Cairo' date Mon Oct 21 15:45:21 EET 2019
この env
コマンドの例では、引数 TZ='Africa/Cairo'
によって TZ
環境変数が変更され、その他は現在のセッションと同じ環境変数を使用して、新しいサブシェルセッションでコマンド(date
)を実行します。
サマータイム
多くの地域ではサマータイムを採用しており、夏期の時刻を1時間早めています。そのため、システム設定が誤っていると、誤った時刻が表示されてしまうことがあります。
/etc/localtime
ファイルには、オペレーティングシステムが時計を調整するためのデータが含まれています。標準的なLinuxシステムでは、/usr/share/zoneinfo/
ディレクトリにすべてのタイムゾーンのファイルが置かれ、/etc/localtime
はそのディレクトリ内のデータファイルへのシンボリックリンクになっています。/usr/share/zoneinfo/
内のファイルは、対応するタイムゾーンの名前で整理されていて、例えば America/Sao_Paulo
タイムゾーンのデータファイルは /usr/share/zoneinfo/America/Sao_Paulo
になります。
サマータイムの定義は(地域の都合で)変更されることがあるため、/usr/share/zoneinfo/
内のファイルを最新の状態に保つことが重要です。タイムゾーンファイルが新しいバージョンに更新されるたびに、ディストリビューションのパッケージ管理ツールでupgradeコマンドを使ってそれらを更新する必要があります。
言語と文字エンコード
Linuxシステムでは、ロケール(locale)
と呼ばれる、様々な言語や非西洋の文字エンコーディングを使用することができます。環境変数 LANG
を定義することで、最も基本的なロケールの設定を行い、ほとんどのプログラムはこの変数から使用する言語を決定します。
LANG
変数の値は ab_CD
という形式であり、ここで ab
は言語コード、CD
は地域コードです。言語コードはISO-639(言語名コード規格)に、地域コードはISO-3166(国名コード規格)に、それぞれ準拠します。たとえば、ブラジルのポルトガル語を使用する場合は、LANG
変数に pt_BR.UTF-8
を定義します。(訳注: 日本語の場合は ja_JP.UTF-8
など。)
$ echo $LANG pt_BR.UTF-8
サンプルに示すように、LANG
変数には(言語と地域だけでなく)文字エンコードも含まれます。電子通信で広く使用された最初の文字エンコード規格は、ASCII(アスキー/American Standard Code for Information Interchange)です。ASCIIは、英語のアルファベットに基づいているため、使用可能な数値の範囲が限られ、アルファベット以外の文字や、言語に固有の記号類は使えません。UTF-8エンコーディングは、西洋文字だけでなく漢字などを含む全世界の文字を一元化した Unicode規格 の一部です。規格の管理者である Unicode Consortium では、コンピュータープラットフォーム間の互換性を確保するために、デフォルトでUTF-8を採用することを推奨しています。
[ Unicode Consortium による Unicodeとは? を引用 ]
Unicode規格は、言語やプラットフォーム、デバイス、アプリケーションなどに関係なく、すべての文字に一意の番号を割り当てるものです。現在では、ソフトウェアプロバイダのほとんどすべてが採用しており、さまざまなプラットフォーム、デバイス、アプリケーション間で、情報を交換できるようになりました。Unicodeをサポートすることで、主要なオペレーティングシステム、検索エンジン、ブラウザ、ラップトップ、スマートフォン、さらにインターネットとWorld Wide Web(URL、HTML、XML、CSS、JSONなど)で、さまざまな言語や文字を表現するための基盤となっています。(..中略..)Unicode規格とそれをサポートするツールを利用することは、グローバルなソフトウェアテクノロジにおける最も重要なトレンドの1つです。
システムによっては、非ASCII文字のエンコードにISOに基づく規格(ISO-8859-1規格など)を使用している場合があります。現在では、このような(Unicode以前の)文字エンコードは非推奨として、Unicodeエンコードを採るべきです。すべての主要なオペレーティングシステムは、デフォルトでUnicodeを採用しています。
システム全体のロケールは、/etc/locale.conf
ファイルで設定します。このファイルで、シェル変数と同様に LANG
などのロケール関連の環境変数を割り当てます。次に例を示します:
$ cat /etc/locale.conf LANG=pt_BR.UTF-8
LANG
環境変数を再定義することで、ユーザーごとに独自のロケールを設定できます。~/.bash_profile
や ~/.profile
などのBashプロファイルに定義を追加すれば、自らのセッションのロケールが変更されます。ただし、ユーザーセッションの外ではデフォルトのシステムロケールが有効となるので、ディスプレイマネージャのログイン画面などは影響を受けません。
Tip
|
システムマネージャーに systemd を採用しているシステムに備わっている |
LANG
環境変数以外にも、通貨記号や数値の区切り方など、ある種のロケールを変更する環境変数があります:
LC_COLLATE
-
文字列の並び替え順を設定します。ファイルやディレクトリをリストする場合などの表示順序が変更されます。
LC_CTYPE
-
文字の分類方法を設定します。たとえば、どの文字を 大文字 または 小文字 と見なすかなどを定義します。(訳注: 日本語ではひらがな・カタカナ、約物(句読点やカンマ、ピリオドなど)などの判定方法が影響を受けます。)
LC_MESSAGES
-
プログラムが表示する文字列の言語を設定します。
LC_MONETARY
-
通貨記号と表現形式を設定します。(訳注: 日本語では円マークと3桁ごとのカンマなどが影響を受けます。)
LC_NUMERIC
-
金額以外の数値の表現形式を設定します。主に3桁ごとの区切り記号や小数点を表す文字など。
LC_TIME
-
日付や時刻の表現形式を設定します。
LC_PAPER
-
標準の用紙サイズを設定します。
LC_ALL
-
LANG
を含む、ロケールに関わるすべての環境変数をオーバーライドします。
locale
コマンドは、現在のロケール構成で定義されているすべての環境変数を表示します。
$ locale LANG=pt_BR.UTF-8 LC_CTYPE="pt_BR.UTF-8" LC_NUMERIC=pt_BR.UTF-8 LC_TIME=pt_BR.UTF-8 LC_COLLATE="pt_BR.UTF-8" LC_MONETARY=pt_BR.UTF-8 LC_MESSAGES="pt_BR.UTF-8" LC_PAPER=pt_BR.UTF-8 LC_NAME=pt_BR.UTF-8 LC_ADDRESS=pt_BR.UTF-8 LC_TELEPHONE=pt_BR.UTF-8 LC_MEASUREMENT=pt_BR.UTF-8 LC_IDENTIFICATION=pt_BR.UTF-8 LC_ALL=
この例では、LC_ALL
のみが未定義で、これを使用してすべてのロケール設定を一時的にオーバーライドできます。次の例は、システムロケールが pt_BR.UTF-8
であるマシンで、LC_ALL
変数をオーバーライドして date
コマンドを実行します:
$ date seg out 21 10:45:21 -03 2019 $ env LC_ALL=en_US.UTF-8 date Mon Oct 21 10:45:21 -03 2019
LC_ALL
変数を変更したので、月名と曜日がアメリカ英語(en_US
)で表示されています。なお、すべての変数に同じロケール値を設定する必要はありません。たとえば、言語を pt_BR
として、数値形式(LC_NUMERIC
)を米国式とすることができます。
ローカライゼーションの設定によって、プログラムが文字列の並び順や数値の書式を扱う方法が変わります。ほとんどのプログラムは一般的なロケールを正しく処理できますが、一部の(古い)スクリプトなどは、例えば文字列の並び順を変更すると予期しない動作をすることがあります。このような場合には、LANG=C
として環境変数 LANG
に C
ロケールを設定すると、うまく動くことがあります。Cロケールは、(ロケールの概念が登場する前の)伝統的なUNIX環境を指定するもので、ASCIIエンコードを使用して単純なバイト列として文字列の比較を行います。国際化の処理を行わないので単純で高速ですが、米国英語以外の言語はほぼ使えないと考えて下さい。
エンコーディング変換
異なる文字エンコーディングのシステムで作成したテキストを表示すると、意味不明な文字が表示されることがあります。iconv
コマンドを使うと、ファイルの文字エンコーディングを別のものに変換することができます。たとえば、ISO-8859-1(訳注: ラテンアルファベット191文字を、1文字1バイトで表現す規格)でエンコードされている original.txt
というファイルを、UTF-8 に変換して converted.txt
というファイルに書き込むには、以下のコマンドを使用します:
$ iconv -f ISO-8859-1 -t UTF-8 original.txt > converted.txt
オプション -f ISO-8859-1
(--from-code=ISO-8859-1
)は元のファイルのエンコーディングを、オプション -t UTF-8
(--to-code=UTF-8
)は、変換後のファイルのエンコーディングをそれぞれ指定します。iconv
コマンドがサポートしているすべてのエンコーディングは、iconv -l
または iconv --list
で一覧表示されます。例では出力のリダイレクトを使用していますが、-o converted.txt
(--output converted.txt
)オプションで出力ファイルを指定することもできます。
訳注: Unicode以前に、日本語かな漢字では大別して3種類のエンコーディングが使用されていました: 1)JIS漢字コード(ISO-2022-JPなど)、2)日本語EUC(EUC-JPなど)、3)シフトJIS漢字(SJISなど)。現在、これらの文字エンコードを使用する事はほとんどありませんが、古い文書ファイルなどを読み出す時に変換が必要となることがあります。日本語に特化した nkf
(Network Kanji filter)という変換コマンドが、ほとんどのLinuxディストリビューションで利用できます(インストールが必要です)から、必要な場合には調べてみて下さい。iconv
は規格に則った融通の利かないツールですが、nkf
は実情に合わせた柔軟な処理を行い、現在もメンテナンスされています。
演習
-
以下の
date
コマンドの出力から推測して、システムのタイムゾーンをGMT表記で書いて下さい。$ date Mon Oct 21 18:45:21 +05 2019
-
システムデフォルトのローカルタイムを
Europe/Brussels
にする場合、/etc/localtime
シンボリックリンクが指すファイルは何ですか? -
システムの文字エンコーディングと、テキストファイルの文字エンコーディングが異なる場合、正しく表示されないことがあります。
iconv
を使用して、WINDOWS-1252でエンコードされたファイルold.txt
を、UTF-8 でエンコーディングされたnew.txt
ファイルに変換するにはどうしますか?
発展演習
-
現在のシェルセッションで、タイムゾーンを
Pacific/Auckland
とするにはどうしますか? -
uptime
コマンドは、システムの ロードアベレージ を小数で表示します。小数点をドットで表記するかコンマで表記するかは、ロケール設定によって異なります。たとえば、ロケールがde_DE.UTF-8
(ドイツの標準ロケール)の場合はコンマですし、en_US.UTF-8
(アメリカ英語)ではドットです。現在のセッションでuptime
コマンドが少数を表示する際に、ドットを使うようにするコマンドはどうなりますか? -
iconv
コマンドは、変換先の文字セットには存在しない文字をすべて疑問符に置き換えます。変換先のエンコーディングの末尾に//TRANSLIT
を追加すると、変換先では存在しない文字を、1つ以上の類似した文字に置き換えます(字訳)。この機能を使用して、readme.txt
という名前のUTF-8テキストファイルをascii.txt
という名前のプレーンASCIIファイルに変換するにはどうすればよいですか?(注: 日本語では使用できない機能です。)
まとめ
このレッスンでは、Linuxシステムの言語とタイムゾーンを設定する方法について説明しました。テキストを正しく表示するために非常に重要であるため、文字エンコードの概念と設定についても説明しました。このレッスンでは、以下ののトピックについて説明しました。
-
Linuxシステムにおいて、シェルセッションのメッセージを表示する言語を選択する方法。
-
現地時刻とタイムゾーンの概念。
-
タイムゾーンを選択して、システム設定を変更する方法。
-
文字エンコードの概念と、それらを変換する方法。
以下のコマンドと手順を紹介しました:
-
ロケールと時刻に関連する環境変数:
LC_ALL
、LANG
、TZ
など。 -
/etc/timezone
-
/etc/localtime
-
/usr/share/zoneinfo/
-
locale
-
tzselect
-
timedatectl
-
date
-
iconv
演習の解答
-
以下の
date
コマンドの出力から推測して、システムのタイムゾーンをGMT表記で書いて下さい。$ date Mon Oct 21 18:45:21 +05 2019
Etc/GMT+5
タイムゾーンです。 -
システムデフォルトのローカルタイムを
Europe/Brussels
にする場合、/etc/localtime
シンボリックリンクが指すファイルは何ですか?リンク
/etc/localtime
は、/usr/share/zoneinfo/Europe/Brussels
を指している必要があります。 -
システムの文字エンコーディングと、テキストファイルの文字エンコーディングが異なる場合、正しく表示されないことがあります。
iconv
を使用して、WINDOWS-1252でエンコードされたファイルold.txt
を、UTF-8 でエンコーディングされたnew.txt
ファイルに変換するにはどうしますか?iconv -f WINDOWS-1252 -t UTF-8 -o new.txt old.txt
で行えます。
発展演習の解答
-
現在のシェルセッションで、タイムゾーンを
Pacific/Auckland
とするにはどうしますか?export TZ=Pacific/Auckland
-
uptime
コマンドは、システムの ロードアベレージ を小数で表示します。小数点をドットで表記するかコンマで表記するかは、ロケール設定によって異なります。たとえば、ロケールがde_DE.UTF-8
(ドイツの標準ロケール)の場合はコンマですし、en_US.UTF-8
(アメリカ英語)ではドットです。現在のセッションでuptime
コマンドが少数を表示する際に、ドットを使うようにするコマンドはどうなりますか?export LC_NUMERIC=en_US.UTF-8
またはexport LC_ALL=en_US.UTF-8
-
iconv
コマンドは、変換先の文字セットには存在しない文字をすべて疑問符に置き換えます。変換先のエンコーディングの末尾に//TRANSLIT
を追加すると、変換先では存在しない文字を、1つ以上の類似した文字に置き換えます(字訳)。この機能を使用して、readme.txt
という名前のUTF-8テキストファイルをascii.txt
という名前のプレーンASCIIファイルに変換するにはどうすればよいですか?(注: 日本語では使用できない機能です。)iconv -f UTF-8 -t ASCII//TRANSLIT -o ascii.txt readme.txt
で行えます。