web-dev-qa-db-ja.com

現在のターミナルセッションでロケールを設定する方法

LANG変数を変更して、urxvt現在のセッションでエンコーディングを変更しようとしています。ただし、すぐには適用されないようです。これが私がすることです:

利用可能なロケール:

$ locale -a
C
en_US.utf8
POSIX
ru_RU.koi8r
ru_RU.utf8

新しいロケールを設定する前に:

$ echo "а" | od -t x1
0000000 d0 b0 0a # good! UTF-8
#       | a ||NL|

後:

$ export LANG=ru_RU.KOI8-R
$ echo "а" | od -t x1
0000000 d0 b0 0a # hm..expect 'c1 0a'

$ urxvt &を実行して新しいurxvtインスタンスをフォークし、最後に必要なものを取得します。

$ echo "а" | od -t x1
0000000 c1 0a

そもそもなぜLANGが動作を変更しないのですか?

8

2つの要因があります。

  • 組み込みのエコーを備えたシェルを使用している可能性があります(ロケールを変更していることをシェルに通知していません)
  • LANGは、最初にチェックされる環境変数ではありません。 locale(7) によると、LC_ALLおよびLC_CTYPEが最初にチェックされます:
デフォルトのロケール
の場合、setlocale(3)の2番目の引数が空の文字列 ""である場合、次の手順を使用して決定されます。
 
 1. null以外の環境変数LC_ALLがある場合、LC_ALLの値
が使用されます。
 
 2. [のいずれかと同じ名前の環境変数がある場合上記の.____。]カテゴリが存在し、nullでない場合、その値はそのカテゴリに使用されます。
 
 
 3. null以外の環境変数LANGがある場合、 
の値LANGが使用されます。

後者については、 locale コマンドの出力を確認してください。これには、使用されるすべての環境変数がリストされています。

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

LANGを変更するだけで他の変数は変更されず、LC_ALLは一般的にそれを行います。

$ export LC_ALL=ru_RU.KOI8-R
$ locale
LANG=ru_RU.KOI8-R
LANGUAGE=
LC_CTYPE="ru_RU.KOI8-R"
LC_NUMERIC="ru_RU.KOI8-R"
LC_TIME="ru_RU.KOI8-R"
LC_COLLATE="ru_RU.KOI8-R"
LC_MONETARY="ru_RU.KOI8-R"
LC_MESSAGES="ru_RU.KOI8-R"
LC_PAPER="ru_RU.KOI8-R"
LC_NAME="ru_RU.KOI8-R"
LC_ADDRESS="ru_RU.KOI8-R"
LC_TELEPHONE="ru_RU.KOI8-R"
LC_MEASUREMENT="ru_RU.KOI8-R"
LC_IDENTIFICATION="ru_RU.KOI8-R"
LC_ALL=ru_RU.KOI8-R
10
Thomas Dickey