Arkanis A blog about random stuff, but mostly programming.

Can't set locale error on Linux

posix, locale, error, utf8, events.mi, university

Some time ago I've written about the virtual machine I got for my video streaming and archiving project events.mi. While the VM did really well during the last month´s some command displayed some strange error messages.

man for example:

man: can't set the locale; make sure $LC_* and $LANG are correct

Special characters like German umlauts were also not correctly displayed on the console. This didn't really was a problem until Subversion refused to operate because of a directory containing a special character.

The quick answer

The locale data is installed but the needed locale is not compiled into the locale archive. You can do this for the "de_DE.utf8" locale with the following command:

$ localedef -i de_DE -f UTF-8 de_DE

The long story

After a quick search I tried to reinstall or reconfigure the locales package but either helped to solve the issue. Since it's obvious that the error is related to locales I did some digging in the POSIX Locale spec. The LANG environment variable was set to "de_DE.utf8" so there was no problem with the settings. However listing the locales showed something strange:

$ locale -a
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_COLLATE to default locale: No such file or directory
C
POSIX

The POSIX spec states that the C and POSIX locales are just placeholders for the default locale. However there is not a single "real" locale (e.g. "de_DE.utf8") in the list and therefore the default locales point nowhere. A quick test of the setlocale() function in a small C program also showed that it always returns NULL and therefore fails.

Now the question is, why are there no real locales installed? I stumbled across a forum post mentioning localedef as a solution to the problem and the man page of localedef shows the directories where the character maps (/usr/share/i18n/charmaps) and "raw" locales (/usr/share/i18n/locales) are stored in a Linux system. These directories contained many character maps and locales but the "compiled" locales in the locale archive (/usr/lib/locale/locale-archive) where simply missing. Therefore locale -a returned only the placeholder locales and setting the "de_DE.utf8" locale failed.

Now localedef is the utility that compiles the raw locales and character maps into the locale archive. So the only thing we have to do is compile the wanted locale:

$ localedef -i de_DE -f UTF-8 de_DE

Now the list of available locales looks like it is supposed to do:

$ locale -a
C
de_DE
de_DE.utf8
POSIX

Now the necessary locales are in the locale archive and therefore all programs can use the setlocale() function again to set the locale to "de_DE.utf8". Directory and file names are also displayed properly and Subversion can handle special characters again.

I hope this detailed description of the error helps a few people solving similar problems. 🙂

react

nice meh bad surprised confused agree disagree

Comments

Newsfeed