I'm using Arch Linux, and I've followed the directions on the wiki about setting my locale.
Nearly every program that runs complains about the locale – even locale
. It looks like this:
% 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=
or:
% 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")
Something slightly confusing is that the /etc/locale.gen
has several examples; all the UTF-8 lines have "something.UTF-8", and running locale-gen
shows en_US.UTF-8... done
while it's running, but locale -a
, which is supposed to show you the available locales shows en_US.utf8
. I've tried various combinations of both formats in /etc/locale-gen
and LOCALE=
in /etc/rc.conf
, but nothing has fixed the problem.
Additional information:
% locale -a
C
POSIX
en_US
en_US.iso88591
en_US.utf8
Bruce Ediger's suggestion of setting LANG=C
and LC_ALL=en_US.UTF-8
worked (in fact, setting LC_ALL
fixed it, setting LANG
didn't matter), but I'd like to know what's happening. According to SUS, LC_ALL will override all the other LC_* variables if it is set and not null. In my system, it is set, but it is null, so it should be ignored, and other values should be used instead. That's not what's happening, it seems that applications are calling setlocale
with LC_ALL
, getting a NULL
back, and generating an error, even when other calls to setlocale
return a good string.
Here is the top of an ltrace
of locale
(scroll right to see function return values)
% 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)
Best Answer
You're missing a file which would be used to default the locale in the absence of
$LANG
or$LC_ALL
(or all of the more specific$LC_whatever
) being set.On older glibc, it's
/usr/lib/locale/locale-archive
. Because GNU/Linux is chaotic, you should use strace to determine which files are expected in the particular versions in use on your machine:----------------------Comments added 1 day later:
ltrace -S
should be okay, since it shows syscalls.Otherwise, "ltrace" is not very helpful (i.e. it's counterproductive versus
strace
), because it only shows the uppermost calls. Those are obvious (setlocale(3)
), whereas the real problem happens withinlibc
.It sounds like you have the raw locale data installed, since
en_US.UTF-8
works.If so, then something like this should fix your problem, setting a system-wide default: