16

I have generated en_US.utf8, et_EE.iso88591 and ru_RU.utf8 localisation files. Now if I try to change any of the locale variables to a ru_RU.utf8 or en_US.utf8, then this does not have any effect:

# locale -a
C
en_US.utf8
et_EE
et_EE.iso88591
POSIX
ru_RU.utf8
# LC_TIME=ru_RU.utf8
# locale | grep LC_TIME
LC_TIME="et_EE.iso88591"
# LC_TIME="ru_RU.utf8"
# locale | grep LC_TIME
LC_TIME="et_EE.iso88591"
# 

However, if I change the LANG= variable, then all other variables but LANGUAGE= and LC_ALL= take the value of the LANG= variable. Is there a way to modify each locale variable separately? In addition, am I correct that locale variables aren't regular shell variables, but more like parameters to locale utility?

12

You can set any locale category independently. LANG applies only to the categories that are not explicitly set.

LANG and LC_xxx are ordinary environment variables. They are not settings for the locale utility: the locale program isn't involved in any locale processing, it's just a small utility to report current and available locale settings.

When you write LC_TIME=ru_RU.utf8, this doesn't set an environment variable, only a shell variable. Shell variables are internal to the shell, they are not seen by other programs. Environment variables, on the other hand, are inherited by the programs that the shell starts. You need to export the variable to the environment as well:

$ LC_TIME=ru_RU.utf8
$ locale | grep LC_TIME
LC_TIME="et_EE.iso88591"
$ export LC_TIME
$ locale | grep LC_TIME
LC_TIME="ru_RU.utf8"

or directly

$ export LC_TIME=ru_RU.utf8
$ locale | grep LC_TIME
LC_TIME="ru_RU.utf8"
  • "LANG and LC_xxx are ordinary environment variables" How do you know that LANG and LC_xxx are environment variables? my testing shows that only LANG and LANGUAGE and LC_MESSAGES and LC_ALL are environment variables, while other variables like LC_CTYPE and LC_MONETARY are not environment variables (also, they are not shell variables)? – rony_t May 30 '18 at 15:06
  • @rony_t You can look at the source code of applications and libraries, look at their documentation, or experiment with them. For example, compate env LC_TIME=en_GB date with env LC_TIME=fr_FR date and env PATH="$PATH" date (obviously, pick locales that exist on your system). Obviously, each variable may or may not be set in a given process's environment. What testing did you do? Are you sure the application you used behaves differently based on LC_CTYPE (fairly common) and LC_MONETARY (pretty rare)? – Gilles May 30 '18 at 18:00
  • In the terminal, I executed the printenv command to list the environment variables of bash, and only LANG and LANGUAGE and LC_MESSAGES and LC_ALL were listed as environment variables. I also executed the command set -o posix followed by the command set to get the environment variables and the shell variables of bash, and only LANG and LANGUAGE and LC_MESSAGES and LC_ALL were listed. So this means that LANG and LANGUAGE and LC_MESSAGES and LC_ALL are environment variables and the rest of the locale variables are not, and also they are not shell variables. – rony_t May 30 '18 at 18:41
  • @rony_t No. It means that you have set the environment variables LANG, LANGUAGE, LC_MESSAGES and LC_ALL. (Either you did this explicitly or your distribution or your system administrator did it for you.) You can set an environment variable by any (syntactically valid) name! But some names are meaningful to some application, and some names aren't. LC_MESSAGES, LC_CTYPE, LC_TIME and so on are used by applications that care about the language of error messages, the character encoding, the time format, and so on. – Gilles May 30 '18 at 19:26
  • @rony_t By the way your configuration is very strange. The setting of LC_ALL overrides all the other settings, so the value of the other locale variables doesn't matter. It's normally only used temporarily to force a program to use a given locale, it doesn't make sense to have it in your normal environment. – Gilles May 30 '18 at 19:27
6

Under the Fedora/CentOS/RHEL based distros I believe you can change the locale to one of the locale's displayed when you run the locale -a command in this system file:

/etc/sysconfig/i18n

For example on my Fedora 14 system:

$ more /etc/sysconfig/i18n 
LANG="en_US.UTF-8"
SYSFONT="latarcyrheb-sun16"

Under GNOME you can run the help app:

system-config-language

Which brings up this GUI:

             ss of lang. gui

I think it's slightly different for the Debian/Ubuntu distros. I believe it's this file:

/etc/default/locale

I believe they're environment variables but not entirely sure how applications make use of them if at all.

References

2

On RedHat 6 at least, note that if LC_ALL is set, then setting other LC_* environment variables will have no effect, as LC_ALL takes precedence over all other LC_* environment variables.

[root@nbu76 bin]# LC_TIME=en_US.UTF-8
[root@nbu76 bin]# export LC_TIME
[root@nbu76 bin]# locale
LANG=en_US.UTF-8
LC_CTYPE="en_IE"
LC_NUMERIC="en_IE"
LC_TIME="en_IE"
...
LC_ALL=en_IE
[root@nbu76 bin]# unset LC_ALL
[root@nbu76 bin]# locale
LANG=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME=en_US.UTF-8
...
LC_ALL=
[root@nbu76 bin]# export LC_TIME=en_IE
[root@nbu76 bin]# locale
LANG=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME=en_IE
....
LC_ALL=
1

In Debian systems, one can run dpkg-reconfigure locales to set the main language and make others available; then one can run update-locale to set the LANGUAGE environment variable in /etc/default/locale to have fallback languages.

  • 2
    dpkg-reconfigure locales, not locale – lauriys Apr 17 '18 at 12:56

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.