1. 概要

このチュートリアルでは、Linuxに存在する標準のロケール環境変数について説明します。 いくつかの例とユースケースを取り上げ、それらがどのように機能するかを見ていきます。

その過程で、OSで使用される言語、時間、さらには文字エンコードを扱うときに、さまざまなシナリオで役立つことがわかります。

2. 環境変数の優先度

ロケール環境変数は、特定の種類のテキストを表示または出力する方法をOSに指示します。 それらは優先順位が付けられており、さまざまなシナリオでどちらが機能するかに影響を与えることができます。

  1. 言語
  2. LC_ALL
  3. LC_xxx 、ロケールカテゴリを考慮
  4. LANG

たとえば、 LANG を使用してフランス語を言語として設定できますが、LC_TIMEを使用してアメリカの日時形式で設定できます。

この優先順位スキームがどのように機能するかを確認するために、さまざまなロケール変数を詳しく見てみましょう。

3. ロケール環境変数

ロケール環境変数に入る前に、localeコマンドを使用して現在の設定を出力しましょう。

$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=ro_RO.UTF-8
LC_TIME=ro_RO.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=ro_RO.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=ro_RO.UTF-8
LC_NAME=ro_RO.UTF-8
LC_ADDRESS=ro_RO.UTF-8
LC_TELEPHONE=ro_RO.UTF-8
LC_MEASUREMENT=ro_RO.UTF-8
LC_IDENTIFICATION=ro_RO.UTF-8
LC_ALL=

次に、これらの変数が出力にどのように影響するかを観察し、それらが他の環境変数とどのように相互作用して機能するかを確認します。

3.1. LANG

LANG 環境変数は、Linuxシステムの言語を扱います。 LANG変数を使用して言語を指定すると、その変数を使用して、選択した言語でメッセージが出力されます。 言語が設定されていない場合、またはメッセージにその言語の翻訳がない場合、デフォルトで英語になります。

$ export LANG=es_ES.UTF-8
$ man man
MAN(1) Utilidades del paginador del manual MAN(1)

NOMBRE
man - interfaz de los manuales de referencia del sistema

SINOPSIS
man [opciones de man] [[sección] página ...] ...
// ...

$ man cat
CAT(1)                                           User Commands

NAME
       cat - concatenate files and print on the standard output

SYNOPSIS
       cat [OPTION]... [FILE]...
// ...

ここでは、「manman」コマンドの出力を印刷するためにスペイン語がどのように使用されているかを確認できます。 また、「 man cat 」コマンドにはスペイン語の翻訳がないため、デフォルトで英語が使用されることもわかりました。

3.2. LC_xxx

次に、いくつかの LC_xxx変数と、それらがスペイン語の新しいLANG設定とどのように相互作用するかを見ていきます。

これらの最初のものはLC_TIMEであり、これは日付と時刻の形式で機能します。 たとえば、ある国から別の国に移転し、システムをその国の日時形式に適合させたい場合に便利です。

$ date
joi 25 iunie 2020, 22:58:30 +0300
$ export LC_TIME=en_US.UTF-8
$ date
Thu 25 Jun 2020 10:58:30 PM EEST

最初のコマンドでは、LC_TIME変数がro_RO.UTF-8に設定されているため、ルーマニア語形式で日付が表示されます。 アメリカ英語に変更すると、同じ日時が表示されますが、異なる形式で報告されます。

LC_MESSAGESは、 LANG と同様に、特定の言語でメッセージを印刷する役割を果たします。 これはLC_xxx変数セットの一部であるため、はLANG変数をオーバーライドします。 確認しよう:

$ locale | grep -w LANG
LANG=en_US.UTF-8
$ export LC_MESSAGES=de_DE.UTF-8
$ man man
MAN(1)                                      Dienstprogramme für Handbuchseiten
BEZEICHNUNG
       man - eine Oberfläche für die System-Referenzhandbücher

ÜBERSICHT
       man [man Optionen] [[Abschnitt] Seite ...] ...
// ...

注目すべきもう1つのロケール環境変数は、 LC_NUMERICであり、OSによって出力される数値のフォーマットを担当します。

$ env LC_NUMERIC=en_US.UTF8 printf '%f\n' 1233.14
1233.140000
$ env LC_NUMERIC=de_DE.UTF8 printf '%f\n' 1233.14
1233,140000

ここでは、セパレーターに2つの数値形式の違いがあります。

他のLC_xxx環境変数も重要であり、特定のシナリオで役立ちます。 それらを適切に使用する方法を知る必要があります。

3.3. LC_ALL環境変数

LC_ALL は、 LANGUAGE を除いて、最も強力なロケール環境変数です。 これは、優先順位が他のすべての変数をオーバーライドし、ロケール設定が必要なときにシステムによって最初にチェックされます。 したがって、注意して使用する必要があります。解決しようとしている問題に対する他の解決策がない場合にのみ使用してください。

通常、この環境変数は、ユーザーの干渉を望まないスクリプトまたはプロシージャで使用します。スクリプトの実行を終了するときに、以前の値にリセットする必要があります。

LC_ALL をUTF-8エンコーディングで英語に設定すると、ロケール環境変数がどうなるか見てみましょう。

$ export LC_ALL=en_EN.UTF-8 ## setting LC_ALL to English with UTF-8 encoding
$ locale
LANG=es_ES.UTF-8
LANGUAGE=en_US
LC_CTYPE="en_EN.UTF-8"
LC_NUMERIC="en_EN.UTF-8"
LC_TIME="en_EN.UTF-8"
LC_COLLATE="en_EN.UTF-8"
LC_MONETARY="en_EN.UTF-8"
LC_MESSAGES="en_EN.UTF-8"
LC_PAPER="en_EN.UTF-8"
LC_NAME="en_EN.UTF-8"
LC_ADDRESS="en_EN.UTF-8"
LC_TELEPHONE="en_EN.UTF-8"
LC_MEASUREMENT="en_EN.UTF-8"
LC_IDENTIFICATION="en_EN.UTF-8"
LC_ALL=en_EN.UTF-8

ここでは、LC_ALL変数が他のすべてのロケール環境変数をオーバーライドしていることがわかります。 LC_ALL が存在する限り、設定を変更することはできません。

$ export LC_MESSAGES=de_DE.UTF-8
$ locale
LANG=es_ES.UTF-8
LANGUAGE=en_US
LC_CTYPE="en_EN.UTF-8"
LC_NUMERIC="en_EN.UTF-8"
LC_TIME="en_EN.UTF-8"
LC_COLLATE="en_EN.UTF-8"
LC_MONETARY="en_EN.UTF-8"
LC_MESSAGES="en_EN.UTF-8"
LC_PAPER="en_EN.UTF-8"
LC_NAME="en_EN.UTF-8"
LC_ADDRESS="en_EN.UTF-8"
LC_TELEPHONE="en_EN.UTF-8"
LC_MEASUREMENT="en_EN.UTF-8"
LC_IDENTIFICATION="en_EN.UTF-8"
LC_ALL=en_EN.UTF-8

リセットするには、空の値をLC_ALLにエクスポートできます。

$ export LC_ALL=
$ locale
LANG=es_ES.UTF-8
LANGUAGE=en_US
LC_CTYPE="es_ES.UTF-8"
LC_NUMERIC=en_EN.UTF-8
LC_TIME=en_EN.UTF-8
LC_COLLATE="es_ES.UTF-8"
LC_MONETARY=en_EN.UTF-8
LC_MESSAGES=de_DE.UTF-8
LC_PAPER=en_EN.UTF-8
LC_NAME=en_EN.UTF-8
LC_ADDRESS=en_EN.UTF-8
LC_TELEPHONE=en_EN.UTF-8
LC_MEASUREMENT=en_EN.UTF-8
LC_IDENTIFICATION=en_EN.UTF-8
LC_ALL=

ここで、 LC_ALL 環境変数をリセットすると、ロケール設定がエクスポート前の状態にリセットされることがわかります。

3.4. LC_ALLおよびsortコマンド

LC_ALL を特定の値「C」に設定することは、バイト単位の並べ替えを使用しながら、ロケールにデフォルト言語を使用させるためのシンプルで強力な方法です。 

次に、LC_ALL変数がsortコマンドの結果をどのように変更するかを見てみましょう。

letters.txtファイルがあるとしましょう。

$ cat letters.txt
b
B
A
c
a
C
D
d

sortコマンドを使用してファイルを並べ替えることができます。

$ sort letters.txt 
a
A
b
B
c
C
d
D

上記の出力は、文字がアルファベット順にソートされていることを示しています。

ただし、ASCIIコードでファイルを並べ替えたい場合があります。 その場合、 LC_ALL =” C” を設定して、並べ替えをバイト単位で強制することができます。

$ LC_ALL="C" sort letters.txt 
A
B
C
D
a
b
c
d

上記のコマンドで、 LC_ALL =” C” 設定は、ソートコマンドの実行に対してのみLC_ALL変数を変更することに注意してください。 現在のシェルのLC_ALL環境変数は変更されません。

3.5. 言語

LANGUAGE環境変数は、1つ以上の言語値を持つことができ、メッセージが表示される言語の順序を担当します LC_ALL 環境変数が設定されている場合に変更できるのは、これが唯一の環境変数です。

実際の動作を見てみましょう。

$ export LC_ALL=en_US.UTF-8
$ export LANGUAGE=fr_FR:en_EN
$ man man
MAN(1)                                 Utilitaires de l'afficheur des pages de manuel

NOM
       man - an interface to the system reference manuals

SYNOPSIS
       man [man options] [[section] page ...] ...
// ...

LC_ALL を英語に設定していても、表示されているテキストに既存のフランス語の翻訳がいくつかあり、 LC_ALL によって上書きされるため、あちこちにフランス語があります。 ] LANGUAGE 、それは私たちにそのフランス語のテキストを示しています。

4. 結論

この記事では、言語などのロケール設定を変更し、それらを他の環境変数で部分的または完全にオーバーライドする方法を学びました。

また、Linux環境のロケール設定全体を設定およびリセットする方法と、ロケール固有のメッセージを表示するときにOSがロケール変数の優先順位チェーンでどのように機能するかについても説明しました。