Почему почти все программы жалуются на мою локаль?

Почему почти все программы жалуются на мою локаль?

Я использую Arch Linux и следую инструкциям на сайте.викио настройке моего региона.

Почти каждая запущенная программа жалуется на локаль - даже locale. Выглядит это примерно так:

% locale
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=
LC_CTYPE=en_US.UTF-8
LC_NUMERIC=en-US
LC_TIME=en-US
LC_COLLATE="POSIX"
LC_MONETARY=en-US
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT=en-US
LC_IDENTIFICATION="POSIX"
LC_ALL=

или:

% perl
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
    LANGUAGE = (unset),
    LC_ALL = (unset),
    LC_TIME = "en-US",
    LC_NUMERIC = "en-US",
    LC_MONETARY = "en-US",
    LC_MEASUREMENT = "en-US",
    LC_CTYPE = "en_US.UTF-8",
    LANG = (unset)
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C")

Немного сбивает с толку то, что в /etc/locale.genесть несколько примеров; все строки UTF-8 содержат "something.UTF-8", и запуск locale-genпоказывает, en_US.UTF-8... doneпока он работает, но locale -a, который должен показывать вам доступные локали, показывает en_US.utf8. Я пробовал различные комбинации обоих форматов в /etc/locale-genи LOCALE=в /etc/rc.conf, но ничего не решило проблему.

Дополнительная информация:

% locale -a
C
POSIX
en_US
en_US.iso88591
en_US.utf8

Предложение Брюса Эдигера установить LANG=Cи LC_ALL=en_US.UTF-8сработало (на самом деле, установка LC_ALLисправила это, установка LANGне имела значения), но я хотел бы знать, что происходит. СогласноСУС, LC_ALL переопределит все остальные переменные LC_*, если она установлена ​​и не равна нулю. В моей системе она установлена, но равна нулю, поэтому ее следует игнорировать, а вместо нее следует использовать другие значения. Это не то, что происходит, похоже, что приложения вызывают setlocaleс LC_ALL, получают ответ NULLи генерируют ошибку, даже когда другие вызовы setlocaleвозвращают правильную строку.

Вот верхняя часть ltrace( localeпрокрутите вправо, чтобы увидеть возвращаемые значения функции)

% ltrace locale
(0, 0, 0, -1, 0x7f5c1ae44510)                                                                      = 0x7f5c1ae47140
__libc_start_main(0x401d70, 1, 0x7fff7c8cfbf8, 0x404610, 0x4046a0 <unfinished ...>
setlocale(0, "")                                                                                   = "en_US.UTF-8"
setlocale(5, "")                                                                                   = "en_US.UTF-8"
textdomain("libc")                                                                                 = "libc"
argp_parse(0x607280, 1, 0x7fff7c8cfbf8, 0, 0x7fff7c8cfad4)                                         = 0
setlocale(6, "")                                                                                   = NULL
dcgettext(0, 0x405aa8, 5, 0, 0)                                                                    = 0x405aa8
error(0, 2, 0x405aa8, 1, 0locale: Cannot set LC_ALL to default locale: No such file or directory)  

решение1

У вас отсутствует файл, который использовался бы для установки локали по умолчанию при отсутствии $LANGили $LC_ALL(иливсеболее конкретного $LC_whatever) устанавливается.

В старых glibc это /usr/lib/locale/locale-archive. Поскольку GNU/Linux хаотичен, вам следует использовать strace, чтобы определить, какие файлы ожидаются в конкретных версиях, используемых на вашей машине:

strace -e файл локали
execve("/usr/bin/locale", ["locale"], [/* 36 переменных */]) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (Нет такого файла или каталога)
открыть("/etc/ld.so.cache", O_RDONLY) = 3
открыть("/lib/libc.so.6", O_RDONLY) = 3
открыть("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3

----------------------Комментарии добавлены 1 день спустя:

ltrace -Sвсе должно быть в порядке, так как он показывает системные вызовы.

В противном случае "ltrace" не очень полезен (т. е. контрпродуктивен по сравнению с strace), поскольку он показывает только самые верхние вызовы. Они очевидны ( setlocale(3)), тогда как настоящая проблема происходит внутри libc.

Похоже, у вас естьсыройДанные локали установлены, с тех пор en_US.UTF-8работают.

Если это так, то что-то вроде этого должно решить вашу проблему, установив системное значение по умолчанию:

localedef -f UTF-8 -i en_US en_US.UTF-8

решение2

У меня возникла та же проблема после настройки /etc/locale.confбуквально сегодня (связанная с недавними изменениями в ) /etc/rc.conf. В моем случае оказалось, что локали не были установлены.

Проверьте /etc/locale.gen. Все локали, на которые ссылаются переменные среды, должны быть активированы (т.е. не закомментированы) там. После внесения изменений запустите sudo locale-genустановку выбранных локалей.

решение3

Следуя этомусвязьрешает мою проблему:

sudo localectl set-locale LANG=en_CA.UTF-8
# or change to en_US.UTF-8 depends on your locale-gen

он создает файл /etc/locale.conf, который исправляет эту проблему

решение4

Может быть, одна из настроек недействительна? Вот мои настройки локали для справки; они не вызывают никаких ошибок (KUbuntu 12.04):

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

Связанный контент