Why doesn't locale -a just report the two actual locales on my system?

Also why is utf8 reported as the character set rather than UTF-8?

In trying to do a Debian dist-upgrade, but I'm getting lots of warnings and one fatal message about my locales not being setup correctly. So I went investigating and learning...

man locale says:

-a, --all-locales
Display a list of all available locales. The -v option causes the LC_IDENTIFICATION metadata about each locale to be included in the output.

Here's what I'm seeing on Debian, Stretch, 9.6:

$ locale -a    #Lists these 4 locales:

and with the additional -v option:

$ locale -av    #Only lists these 2 locales:
locale: en_US.utf8      archive: /usr/lib/locale/locale-archive
    title | English locale for the USA
   source | Free Software Foundation, Inc.
  address | http://www.gnu.org/software/libc/
    email | bug-glibc-locales@gnu.org
 language | American English
territory | United States
 revision | 1.0
     date | 2000-06-24
  codeset | UTF-8

locale: C.UTF-8         directory: /usr/lib/locale/C.UTF-8
    title | C locale
    email | aurel32@debian.org
 language | C
 revision | 1.6
     date | 2016-08-08
  codeset | UTF-8

Notice the following:

  • Adding the -v changes the number of items reported! It's only suppose to "add metadata about each locale to be included in the output." locale -a seems to report locales and also aliases, and at that, only some of the many valid aliases. To me it looks like C and POSIX here are really just aliases of the C.UTF-8 locale. I find this all very confusing.

  • Also en_US.utf8 (lower case 'utf' and without a dash before the 8) I think should probably be en_US.UTF-8 (upper case 'UTF' and with a dash before the 8) which is the name of the actual character set (more on that below).

Here's what I also found:

1) From man 3 setlocale

A locale name is typically of the form language[_territory][.codeset][@modifier], where ... codeset is a character set or encoding identifier like ISO-8859-1 or UTF-8.

Then from man 5 charmap,

Syntax The charmap file starts with a header that may consist of the following keywords:

  is followed by the name of the character map.


        Usual default character map path.

Looking inside /usr/share/i18n/charmaps/UTF-8.gz the first line is:

<code_set_name> UTF-8

So the official codeset name is UTF-8, and not utf8.

(BTW, there is no /usr/share/i18n/charmaps/utf8* [lower case utf] file.)

2) There's a locale alias file for X11 at /usr/share/X11/locale/locale.alias. From this file it can be seen that the following are related:

Column 1 = alias name   Column 2 = full locale name
----------------        ---------------------
POSIX                   C
C.UTF-8                 en_US.UTF-8
en_US.utf8              en_US.UTF-8

This again confirms to me what I've suspected, that I only have 2 locales on my system, and they are C and en_US.UTF-8. But it muddies the prior assumption about what is an alias of what. Clearly POSIX is related to C. But here C.UTF-8 is related to en_US.UTF-8 rather than to C.

3) Finally, if you look at the folders for your locales (via localedef) you see this tree:

$ tree /usr/lib/locale/    #gives:

├── C.UTF-8
│   ├── LC_ADDRESS
│   ├── LC_COLLATE
│   ├── LC_CTYPE
│   │   └── SYS_LC_MESSAGES
│   ├── LC_NAME
│   ├── LC_NUMERIC
│   ├── LC_PAPER
│   └── LC_TIME
└── locale-archive

locale -av reported that

  • the en_US.utf8 locale is an 'archive' at /usr/lib/locale/locale-archive, and
  • the C.UTF-8 locale is in a 'directory' at /usr/lib/locale/C.UTF-8.

That makes sense, because C.UTF-8 is the default built in locale, and en_US.utf8 is the compiled (added on by the bash script local-gen which calls localedef to do the actual compiling and installing) locale.

This seems to confirm that the C locale is really named C.UTF-8.

Furthermore some experimentation with deleting and re-creating the locale-archive shows that it contains the en_US.UTF-8 locale, and that C.UTF-8/ contains the C locale, at least as reported by locale -a.

So what's going on with locale -a vs local -av? Any ideas?


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.