7

How to remove system locales, as oppose to package locales as asked in How to remove unnecessary locales??

I'm getting the following errors recently:

locale: Cannot set LC_ALL to default locale: No such file or directory

The only en locale I have in my system:

$ grep -r en /var/lib/locales/supported.d/*
/var/lib/locales/supported.d/local: en_US ISO-8859-1
/var/lib/locales/supported.d/local: en_US.UTF-8 UTF-8

$ locale -a | grep en en_US en_US.iso88591 en_US.utf8

but not en, as complained by perl:

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = "",
        LC_ALL = (unset),
        LC_MEASUREMENT = "en",
        LC_PAPER = "en",
        LC_MONETARY = "en",
        LC_NAME = "en",
        LC_ADDRESS = "en",
        LC_NUMERIC = "en",
        LC_TELEPHONE = "en",
        LC_IDENTIFICATION = "en",
        LC_TIME = "en",
        LANG = "C"

So I add the locale en by:

% locale-gen en
Generating locales (this might take a while)...
  en_AG.UTF-8... done
  en_AU.UTF-8... done
  en_BW.UTF-8... done
  en_CA.UTF-8... done
  en_DK.UTF-8...^C

I don't want any of above locales (only en_US), but now I can't get rid of them -- I followed the steps in https://serverfault.com/questions/394610/remove-a-locale-in-ubuntu

But when it comes to the last step, I'm still getting:

% locale-gen
Generating locales (this might take a while)...
  en_AG.UTF-8... done
  en_AU.UTF-8... done
  en_BW.UTF-8... done
  en_CA.UTF-8... done
  en_DK.UTF-8...^C

How to remove all above locales and keep only en_US?

Conclusion & Supplement

Thanks to Gunnar's answer, it is indeed caused by entries in /etc/locale.gen, for those extra locales. Just FTR, this is what locale-gen en has changed in /etc/locale.gen:

$ sed '/^#/d; /en/p;' /etc/locale.gen

en_AG UTF-8 en_AG UTF-8 en_AU.UTF-8 UTF-8 en_AU.UTF-8 UTF-8 en_BW.UTF-8 UTF-8 en_BW.UTF-8 UTF-8 en_CA.UTF-8 UTF-8 en_CA.UTF-8 UTF-8 en_DK.UTF-8 UTF-8 en_DK.UTF-8 UTF-8 en_GB.UTF-8 UTF-8 en_GB.UTF-8 UTF-8 en_HK.UTF-8 UTF-8 en_HK.UTF-8 UTF-8 en_IE.UTF-8 UTF-8 en_IE.UTF-8 UTF-8 en_IL UTF-8 en_IL UTF-8 en_IN UTF-8 en_IN UTF-8 en_NG UTF-8 en_NG UTF-8 en_NZ.UTF-8 UTF-8 en_NZ.UTF-8 UTF-8 en_PH.UTF-8 UTF-8 en_PH.UTF-8 UTF-8 en_SC.UTF-8 UTF-8 en_SC.UTF-8 UTF-8 en_SG.UTF-8 UTF-8 en_SG.UTF-8 UTF-8 en_US.UTF-8 UTF-8 en_US.UTF-8 UTF-8 en_ZA.UTF-8 UTF-8 en_ZA.UTF-8 UTF-8 en_ZM UTF-8 en_ZM UTF-8 en_ZW.UTF-8 UTF-8 en_ZW.UTF-8 UTF-8

As a comparison, here is what the default looks like (i.e., without any of the above extra locales):

$ sed '/^#/d;' /etc/locale.gen; echo ---

xpt
  • 1,045

3 Answers3

6

You should edit /etc/locale.gen and comment the locales you don't want. Then run

sudo locale-gen

There does not exist any locale with the name en. The one you probably want to use is en_US.UTF-8 and not en_US. (The latter enables latin1 encoding.)

Gunnar Hjalmarsson
  • 33,540
  • 3
  • 64
  • 94
6

Note: Some of the commands below require root privileges, consider the use of sudo.

Basic info

According to man locale-gen, locales are set in several files.

/etc/locale.gen

The main configuration file, which has a simple format: every line that is not empty and does not begin with a # is treated as a locale definition that is to be built.

/var/lib/locales/supported.d/

A directory containing locale.gen snippets provided by language-pack packages. Do not edit these manually, they will be overwritten on package upgrades.

Locales are compiled (generated) into a single file.

/usr/lib/locale/locale-archive

Usual default locale archive location.

Comprehensive details on locales at the Arch Wiki.

Checking locales and the locale

To list available (known) locales, run any of the following commands (with minor output differences).

locale -a
localectl list-locales

To check the (already) generated locales, run the following command.

localedef --list-archive

To check the currently used locale, run any of the following commands (with minor output differences).

locale
localectl

Setting and generating (new) locales

Locales are typically set by uncommenting lines in /etc/locale.gen, after which running locale-gen is required.

nano /etc/locale.gen # uncomment desired lines (locales)
locale-gen

This will compile (generate) locales into /usr/lib/locale/locale-archive for each uncommented line in /etc/locale.gen and under /var/lib/locales/supported.d/, whether they were previously compiled or not.

Alternatively, the command

locale-gen <locale>

will uncomment the corresponding line in locale-gen while generating the desired locale and only this one.

Note: The implementation of locale-gen is distro dependent. For instance, the command above is valid in Ubuntu/Debian but not in ArchLinux.

Removing locales

When issuing locale-gen, the compiled archive is erased and all locales in /etc/locale.gen and under /usr/lib/locale/locale-archive are regenerated anew. The command locale-gen --purge <locale> doesn't do what the modifier suggests but the opposite: It removes all compiled locales except those indicated. To make sure only specific locales are generated when locale-gen is issued or and update is performed both /etc/locale.gen and /usr/lib/locale/locale-archive must be considered.

To remove locales in /etc/locale.gen, simply comment the desired lines and regenerate the locales using locale-gen.

To remove locales under /var/lib/locales/supported.d/ is trickier. Since any file /var/lib/locales/supported.d/<code> depends on the package language-pack-<code>-base, any change on the former will be restored when the latter is updated. To solve this, simply hold the packages that update files under /var/lib/locales/supported.d/. The command that achieves this in Ubuntu/Debian is the following.

apt-mark language-pack-<code>-base

To update a held package, you must unmark it or simply --ignore-hold.

Workaround. A more intrusive but general solution that prevents changes under /var/lib/locales/supported.d/ is to set files in it with the "immutable (i)" attribute. So instead of removing files, empty them. For instance:

cd /var/lib/locales/supported.d/
rm <code> && touch <code> # <code> has been emptied
lsattr <code>    # regular attributes
chattr +i <code> # adding (+) immutable
lsattr <code>    # checking attributes

Setting the locale

Setting and generating locales does not set the system locale. Any of the following commands achieves this.

echo LANG=<code> | sudo tee /etc/locale.conf # reboot (might be ignored in Ubuntu)
localectl set-locale LANG=<code>
1

Which locales are installed on my machine?

You can check which locales are generated and configured on your system using the locale command:

  • locale ... list the current locale configuration
  • locale -a ... lists all all locales that were generated on your system
  • locale -a -v ... list all locales and show useful additional information (such as directory names that contain the locale information data files)

The last command from above makes you see that all generated locales are located in /usr/lib/locale/, and you may remove any of them if unneeded. Each pack of locale information is a directory containing text files and other directories.


Supported locales

All locales that you want your system to support are listed in the text files in /var/lib/locales/supported.d/. These files have two columns, language tag and character map.

I want my system to know US-English only, so I have only one file there, called en, which contains just a single line:

en_US UTF-8

Error messages

If error messages are displayed when issuing the locale command, e.g.

locale: Cannot set LC_ALL to default locale: No such file or directory

make sure the file /etc/default/locale exists and has proper content, such as:

LANG="en_US"
LANGUAGE="en_US:en"

Get rid of unneeded locale data - Step by step

Now we know all the necessary details to get started with cleaning up our system's locale information:

  1. Edit the locale file(s) in /var/lib/locales/supported.d/, and remove all unneeded locales (one locale per line)
  2. Create and edit /etc/default/locale (see above for an example)
  3. Delete all generated locale data: rm -rfv /usr/lib/locale/*
  4. Re-generate new locales: locale-gen

That's all! Reboot your machine to make your changes take effect. Then run one or more of the locale command examples from above to ensure yourself that the result is as expected.


Reference:

https://www.linuxquestions.org/questions/blog/bittner-195120/remove-unwanted-locales-on-ubuntu-debian-3281/

Paulo Coghi
  • 2,024
  • Not able to solve my specific problem, as explained in "The *only* en locale I have in my system" in OP, but thanks for posting. – xpt Nov 28 '21 at 16:48