locale-gen turns a supported locale entry into something locale -a can actually see. You will select the locale data your Debian or Ubuntu system needs, generate it, and confirm the result; a fresh Ubuntu box rarely has anything but the defaults compiled. Allow about ten minutes, including a quick check of a program that uses the locale.
This guide describes the installed locales package version 2.39-0ubuntu8.9. Its manual page documents --keep-existing, while the installed script also accepts --purge, --archive, --no-archive, --aliases and --lang. The examples use the documented file format and the behaviour of the installed script; do not assume another distribution or package release has the same option set.
Start with read-only checks. None of these need sudo:
$ command -v locale-gen
/usr/sbin/locale-gen
$ dpkg-query -W -f='${Package} ${Version}\n' locales
locales 2.39-0ubuntu8.9
$ locale -a
C
C.utf8
POSIX
en_US.utf8
Your list will differ. The locale -a output is the useful baseline: it shows compiled locales, not every locale that could be generated. If the command is missing, install the locales package through your normal package-management process rather than copying a script from another host.
Checkpoint: record the locale names you already have. You will compare them with the list after generation.
/etc/locale.gen holds whitespace-separated pairs of locale name and character set. A line beginning with # is a comment and is not generated. The installed file points to the supported list at /usr/share/i18n/SUPPORTED:
$ grep '^en_GB' /usr/share/i18n/SUPPORTED
en_GB ISO-8859-1
en_GB.UTF-8 UTF-8
en_GB.ISO-8859-15 ISO-8859-15
en_GB.UTF-8 on its own is not enough; the complete line is en_GB.UTF-8 UTF-8. The same rule applies to any other supported locale, such as fr_FR.UTF-8 UTF-8./var/lib/locales/supported.d; the manual explicitly warns they are overwritten during package upgrades. Use /etc/locale.gen for a local selection instead.Warning: the next action changes system configuration. Save a backup first, and edit as root:
$ sudo cp --preserve=mode,ownership,timestamps /etc/locale.gen /etc/locale.gen.bak
$ sudoedit /etc/locale.gen
Find the exact supported line, remove its leading # and any following space, then save. For the example above, the resulting line should read:
en_GB.UTF-8 UTF-8
Keep unrelated selections as they are. A common distraction is to set LANG=en_GB.UTF-8 in a shell and expect that to compile the locale; it will not. Environment variables choose a locale for a process, they do not create locale data. Only the file plus locale-gen perform the generation. Check the edit before running it:
$ grep -E '^[[:space:]]*[^#[:space:]]+[[:space:]]+[^#[:space:]]+' /etc/locale.gen | grep '^en_GB.UTF-8 UTF-8$'
en_GB.UTF-8 UTF-8
Run the generator with elevated privileges:
$ sudo locale-gen
Generating locales (this might take a while)...
en_GB.UTF-8... done
Generation complete.
The exact progress lines depend on the selections in your file. The command reads /etc/locale.gen and invokes localedef for each active entry, then writes compiled data under /usr/lib/locale, so it can affect every user and every process using the system locale store.
On this installed script, an ordinary run removes existing generated locale data before rebuilding it. Preserving the file alone is not the same as preserving compiled output. If you need to add a locale while keeping existing valid data, use the documented option:
$ sudo locale-gen --keep-existing
This is still a system-wide write. It is not a substitute for checking the requested entry is valid, and it can skip a locale the script already considers usable.
Ask locale -a for the canonical name. Locale names are case-sensitive enough that you should copy the result rather than trust memory:
$ locale -a | grep -E '^en_GB([.]utf8|[.]UTF-8)$'
en_GB.utf8
The spelling in locale -a may be normalised, so en_GB.utf8 is a valid confirmation of the en_GB.UTF-8 UTF-8 source entry. Test a process without touching your login configuration:
$ LC_ALL=en_GB.UTF-8 locale charmap
UTF-8
$ LC_ALL=en_GB.UTF-8 locale date_fmt
%a %d %b %Y %T %Z
These checks apply the locale only to each command. They do not edit /etc/default/locale, your shell startup files or another user's environment.
If generation reports an invalid locale or character set, compare the line with /usr/share/i18n/SUPPORTED. Check both columns, spelling and punctuation; a commented line is also easy to miss in a long file.
To undo only your configuration edit, restore the backup and do not run the generator until you have reviewed it:
$ sudo cp --preserve=mode,ownership,timestamps /etc/locale.gen.bak /etc/locale.gen
$ grep '^en_GB.UTF-8 UTF-8$' /etc/locale.gen || echo 'en_GB selection is no longer enabled'
Restoring the file does not remove already-compiled locale data. If you deliberately ran a rebuild and need the previous compiled set back, there is no general undo command in locale-gen: re-enable the intended entries and run the generator again. Do not delete arbitrary directories under /usr/lib/locale, since that can break programs currently starting with those locales.
For a more detailed error, inspect the individual localedef diagnostics and confirm the source locale and character map exist. Do not silence errors with a guessed locale name. A successful command plus a matching locale -a entry are the completion checks that matter.
/etc/locale.gen./etc/locale.gen is available until the result has been checked.locale-gen completed without a generation error.locale -a lists the generated locale, using its installed spelling.LC_ALL set to that locale reports the expected character map.--keep-existing, and have not changed a persistent login default by accident.