如何在当前终端的会话中设置语言环境?

时间:2017-05-13 12:46:19

标签: bash encoding terminal locale rxvt

我正在尝试通过更改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首先没有改变行为?

1 个答案:

答案 0 :(得分:9)

有两个因素:

  • 您可能正在使用内置回显的shell(并且未通知shell您正在更改区域设置)
  • LANG 不是第一个检查的环境变量。根据{{​​3}},首先会检查 LC_ALL LC_CTYPE
       If the second argument to setlocale(3) is an empty string, "", for
       the default locale, it is determined using the following steps:

       1.     If there is a non-null environment variable LC_ALL, the value
              of LC_ALL is used.

       2.     If an environment variable with the same name as one of the
              categories above exists and is non-null, its value is used for
              that category.

       3.     If there is a non-null environment variable LANG, the value of
              LANG is used.

对于后者,请查看locale(7)命令的输出,该命令列出了将使用的所有环境变量:

$ 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