Safely Change the System Locale with update-locale
Change the wrong locale variable system-wide and update-locale can break every later shell and service. These examples use update-locale from the Ubuntu locales package, version 2.39-0ubuntu8.9, and are worth rehearsing before the real edit.
The route
Jump straight to the step you need, or tick off Done means at the end.
You will change a system-wide setting in /etc/locale.conf, check the result, and know how to reverse it. Allow about ten minutes.
- A shell, the
localespackage, andsudoaccess for the final write. - The investigation and rehearsal steps below need no elevated privileges at all.
Warning
This is persistent configuration. A locale change can affect every later shell session, service and program that reads the file at startup. Keep the old value, and make the real edit in a maintenance window if other users or services depend on it.
1. Check the installed command
Confirm the executable and package version you are working with. This is read-only and needs no sudo:
$ command -v update-locale
/usr/sbin/update-locale
$ dpkg-query -W -f='${Package} ${Version}\n' locales
locales 2.39-0ubuntu8.9
$ update-locale --help
Usage: update-locale [OPTIONS] [LANG=locale] [LC_NUMERIC=locale] ...
The installed help is the contract that matters here. It takes variable assignments such as LANG=C.UTF-8, a bare variable name to remove it, plus --reset, --locale-file=FILE and --no-checks.
2. Inspect the current configuration
Read the target before touching it. On this machine /etc/default/locale is a symlink to the same file, but /etc/locale.conf is the one named in the command's manual:
$ ls -l /etc/locale.conf /etc/default/locale
-rw-r--r-- 1 root root 17 ... /etc/locale.conf
/etc/default/locale -> ../locale.conf
$ sudo cat /etc/locale.conf
LANG=en_US.UTF-8
Use the actual output from your host as your baseline, not what you assume. Do not treat a familiar-looking locale name as proof it is installed: locale -a lists what is actually available to the local runtime.
Checkpoint
Copy the current file somewhere safe before the real edit:
$ sudo cp --preserve=all /etc/locale.conf /etc/locale.conf.update-locale-backup
$ sudo cat /etc/locale.conf.update-locale-backup
3. Rehearse against a disposable file
Make a temporary copy and point update-locale at that path instead. Same file format, none of the risk:
$ testdir=$(mktemp -d)
$ cp /etc/locale.conf "$testdir/locale.conf"
$ update-locale --locale-file="$testdir/locale.conf" LANG=C.UTF-8 LANGUAGE
$ cat "$testdir/locale.conf"
LANG=C.UTF-8
The first argument assigns LANG. The bare LANGUAGE argument removes that variable from the file. Anything else already in the file stays, as long as you skip --reset. Clean up the temporary directory under /tmp however your usual housekeeping does it.
4. Choose the update you actually want
For a normal change, pass each assignment explicitly; you can make several in one call:
$ sudo update-locale LANG=en_GB.UTF-8 LC_TIME=en_GB.UTF-8
$ sudo cat /etc/locale.conf
LANG=en_GB.UTF-8
LC_TIME=en_GB.UTF-8
Only name the variables you actually mean to remove. This keeps LANG and drops LANGUAGE:
$ sudo update-locale LANG=en_GB.UTF-8 LANGUAGE
Warning
Do not reach for --reset casually. It clears every variable you did not supply on the command line, and on this install an omitted entry ends up written as a commented-out line, such as #LC_TIME=C, rather than simply staying active. That is a much bigger change than updating one variable, and it can surprise anyone else reading the file.
5. Verify the file and the active shell
Read the resulting file first: it confirms what was persisted, though it changes nothing in a shell that is already running:
$ sudo cat /etc/locale.conf
LANG=en_GB.UTF-8
LC_TIME=en_GB.UTF-8
$ locale
Start a new login session, or launch a fresh child process, before judging application behaviour. locale reports the current process environment, not a promise that every running service has re-read /etc/locale.conf. Restart only the service that actually needs it, using its own normal restart procedure.
If locale -a does not list the locale you asked for, stop and generate it through your distribution's normal package configuration. --no-checks is not a fix for a missing locale.
6. Handle validation failures
By default, the sanity checks reject an invalid locale value and leave the target unchanged. Rehearse that failure safely first:
$ update-locale --locale-file="$testdir/locale.conf" LANG=not_a_locale
*** update-locale: Error: invalid locale settings: LANG=not_a_locale
$ echo $?
255
$ cat "$testdir/locale.conf"
LANG=C.UTF-8
The exact wording can vary, but a non-zero exit is the signal to go read the error and the file. --no-checks deliberately switches those checks off:
$ update-locale --locale-file="$testdir/locale.conf" --no-checks LANG=not_a_locale
$ cat "$testdir/locale.conf"
LANG=not_a_locale
Warning
This is not a validation workaround. Use it only when you have independently confirmed the value is valid for whatever will read it; an unchecked value can make later commands or services fail somewhere far less obvious.
7. Undo an unwanted change
If the new file is wrong, restore the backup you made earlier. This overwrites the live file, so double-check the source path first:
$ sudo diff -u /etc/locale.conf.update-locale-backup /etc/locale.conf
$ sudo cp --preserve=all /etc/locale.conf.update-locale-backup /etc/locale.conf
$ sudo diff -u /etc/locale.conf.update-locale-backup /etc/locale.conf
Checkpoint
That final diff should produce no output. Keep the backup until you have confirmed the restored configuration and no longer need it. If a service already consumed the bad change, restore the file and then follow that service's own reload or restart procedure.
Done means
- Checked the installed package and syntax. You confirmed
localesand the command's own help. - Backed up before editing.
/etc/locale.confhas a dated copy. - Rehearsed on a disposable copy. Using
--locale-filebefore touching the live file. - Changed only what you meant to. No accidental
--reset. - Verified the saved file. And understood that already-running processes may keep their old environment.
- Know the risk of
--no-checks. And have a tested backup ready if it goes wrong.