0

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:
C
C.UTF-8
en_US.utf8
POSIX

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:

<code_set_name>
  is followed by the name of the character map.

...

FILES  
    /usr/share/i18n/charmaps  
        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:

/usr/lib/locale/
├── C.UTF-8
│   ├── LC_ADDRESS
│   ├── LC_COLLATE
│   ├── LC_CTYPE
│   ├── LC_IDENTIFICATION
│   ├── LC_MEASUREMENT
│   ├── LC_MESSAGES
│   │   └── SYS_LC_MESSAGES
│   ├── LC_MONETARY
│   ├── LC_NAME
│   ├── LC_NUMERIC
│   ├── LC_PAPER
│   ├── LC_TELEPHONE
│   └── 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?

Thanks.

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.