【问题标题】:How to set locale in the current terminal's session?如何在当前终端的会话中设置语言环境?
【发布时间】:2017-10-12 16:39:41
【问题描述】:

我正在尝试通过更改 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 & fork 新的 urxvt 实例,最终得到我想要的:

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

为什么LANG 不首先改变行为?

【问题讨论】:

  • 发布了适用于bash shell 的答案,urxvt 使用哪个登录 shell?
  • urxvt 读取了哪些启动文件,在此处添加更改区域设置的行。它应该在您的所有后续会话中反映出来。
  • 可能它使用了 bash。 add the line with changing locale there - 问题根本不在于更改语言环境,而是在当前会话中更改它。我知道我可以将这一行放在 .bash_profile 或 .bashrc 中——但这不是我想要的。

标签: bash encoding terminal locale rxvt


【解决方案1】:

有两个因素:

  • 您可能正在使用带有内置 echo 的 shell(并且没有通知 shell 您正在更改语言环境)
  • LANG 不是第一个检查的环境变量。根据locale(7),将首先检查LC_ALLLC_CTYPE
如果 setlocale(3) 的第二个参数是一个空字符串,“”,对于 默认语言环境,使用以下步骤确定: 1.如果存在非空环境变量LC_ALL,则取值 使用 LC_ALL。 2.如果环境变量与其中一个同名 上述类别存在且非空,其值用于 那个类别。 3.如果存在非空环境变量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

【讨论】:

  • (and have not informed the shell that you are changing the locale) - 如果是这样,怎么办? cat 的输出相同。顺便说一句,我已经尝试过您对 LC_ALL 的建议 - 仍然不起作用(如果对标准输入编码更明确)。
  • 更改 LANG 未能成功通知 shell,因为它还有其他变量要先检查。
  • 知道了,但有什么解决方案?还是没有办法?
  • 我的示例更改 LC_ALL 显示了解决方案。
  • 无论如何,你不能通过 shell 变量改变终端模拟器的行为。可能有一个转义序列,比如 ESC % G 和 ESC % @
猜你喜欢
  • 2021-03-07
  • 2017-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
相关资源
最近更新 更多