What is the difference between LANG=C and LC_ALL=C?

LANG sets the default locale, i.e. the locale used when no more specific setting (LC_COLLATE, LC_NUMERIC, LC_TIME etc.) is provided; it doesn’t override any setting, it provides the base value. LC_ALL on the other hand overrides all locale settings.

Thus to override scripts’ settings, you should set LC_ALL.

You can check the effects of your settings by running locale. It shows the calculated values, in quotes, for all locale categories which aren’t explicitly set; in your example, LANG isn’t overriding LC_NUMERIC, it’s providing the default value. If LC_ALL and LC_NUMERIC aren’t set in the environment, the locale is taken from LANG, and locale shows that value for LC_NUMERIC, as indicated by the quotes.

See the locales manpage and the POSIX definitions of environment variables for details. See also How does the "locale" program work?


LANG does not override:

$ export LC_NUMERIC="de_DE.UTF-8"
$ export LANG=C
$ printf "%.2f\n" 3.14
-bash: printf: 3.14: invalid number
3,00

But LC_ALL does:

$ export LC_NUMERIC="de_DE.UTF-8"
$ export LC_ALL=C
$ printf "%.2f\n" 3.14
3.14

Tags:

Locale