Как установить локаль в текущей сессии терминала?

Я пытаюсь изменить кодировку в текущей сессии urxvt, изменив LANG переменная. Однако, кажется, что это не относится сразу. Вот что я делаю:

Доступные локали:

$ 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 ответ

Есть два фактора:

  • вы можете использовать оболочку со встроенным эхом (и не сообщили оболочке, что вы меняете локаль)
  • LANG это не первая проверенная переменная окружения. В соответствии с locale(7), LC_ALL а также LC_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
Другие вопросы по тегам