Почему почти каждая программа жалуется на мой язык?

29

Я использую 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 имеют что-то «что-то. 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не имела значения), но я хотел бы знать, что происходит. Согласно SUS , 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)  
Шон Дж. Гофф
источник
можете поделиться выходом locale -a?
njsg
Я собирался указать, что вы должны использовать .utf8в LOCALEи LC_*, но, видимо, .UTF-8работает и здесь ... Что касается en-US: он появляется (без .utf8) в locale -a?
njsg
1
Сделай export LANG=Cи export LC_ALL=en_US.UTF-8посмотри что получится. В моем ноутбуке Arch Linux есть LOCALE="en_US.UTF-8"/etc/rc.conf, и я не могу понять, где мой ноутбук устанавливает LANG = C.
Брюс Эдигер
Можете ли вы опубликовать содержимое вашего /etc/locale.conf? Похоже, вы случайно написали LANG=en-US(с дефисом) вместо LANG=en_US(с подчеркиванием).
Микель
И содержание /etc/locale.genбыло бы тоже полезно.
Микель

Ответы:

18

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

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

strace -e языковой стандарт
execve ("/ usr / bin / locale", ["locale"], [/ * 36 vars * /]) = 0
access ("/ etc / ld.so.preload", R_OK) = -1 ENOENT (такого файла или каталога нет)
open ("/ etc / ld.so.cache", O_RDONLY) = 3
open ("/ lib / libc.so.6", O_RDONLY) = 3
open ("/ 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
Арканзас
источник
sudo localedef -f UTF-8 -i en_US en_US.UTF-8работает по Raspbian 2018-11-13 Lite.
Сиро Сантилли 新疆 改造 中心 法轮功 六四 事件
6

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

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

Стефан Маевский
источник
2

Переход по этой ссылке решает мою проблему:

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

он генерирует файл, /etc/locale.confкоторый решает эту проблему

Kokizzu
источник
1

Недавно у меня были похожие проблемы, все имена файлов Unicode отображались неправильно, когда я случайно удалил 'LOCALE = en_US.utf8' в /etc/rc.conf. Итак, я проверил загрузочный скрипт:

if [[ $DAEMON_LOCALE != [nN][oO] ]]; then
    export LANG=${LOCALE:-C}
    if [[ -r /etc/locale.conf ]]; then
        parse_envfile /etc/locale.conf "${localevars[@]}"
    fi
else
    export LANG=C
fi

Простое решение проверить , как DAEMON_LOCALEи LOCALEв /etc/rc.conf, убедитесь , что первый не был noи второй один не был пуст.

маргаритка
источник
-1

Может быть, одна из ваших настроек недействительна? Это мои настройки локали для справки; они не вызывают никаких ошибок (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=
dwurf
источник