Locale variables have no effect in remote shell (perl: warning: Setting locale failed.)
I have a fresh ubuntu 12.04 installation. When i connect to my remote server i got errors like this:
~$ ssh example.com sudo aptitude upgrade
...
Traceback (most recent call last):
File "/usr/bin/apt-listchanges", line 33, in <module>
from ALChacks import *
File "/usr/share/apt-listchanges/ALChacks.py", line 32, in <module>
sys.stderr.write(_("Can't set locale; make sure $LC_* and $LANG are correct!\n"))
NameError: name '_' is not defined
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
LC_TIME = "de_DE.UTF-8",
LC_MONETARY = "de_DE.UTF-8",
LC_ADDRESS = "de_DE.UTF-8",
LC_TELEPHONE = "de_DE.UTF-8",
LC_NAME = "de_DE.UTF-8",
LC_MEASUREMENT = "de_DE.UTF-8",
LC_IDENTIFICATION = "de_DE.UTF-8",
LC_NUMERIC = "de_DE.UTF-8",
LC_PAPER = "de_DE.UTF-8",
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
locale: Cannot set LC_ALL to default locale: No such file or directory
No packages will be installed, upgraded, or removed.
0 packages upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B of archives. After unpacking 0 B will be used.
...
I don't have this problem when i connect from an older ubuntu installation. This is output from my ubuntu 12.04 installation, LANG and LANGUAGE are set
$ locale
LANG=de_DE.UTF-8
LANGUAGE=de_DE:en_GB:en
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC=de_DE.UTF-8
LC_TIME=de_DE.UTF-8
LC_COLLATE="de_DE.UTF-8"
LC_MONETARY=de_DE.UTF-8
LC_MESSAGES="de_DE.UTF-8"
LC_PAPER=de_DE.UTF-8
LC_NAME=de_DE.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MEASUREMENT=de_DE.UTF-8
LC_IDENTIFICATION=de_DE.UTF-8
LC_ALL=
Does anybody know what has changed in ubuntu to get this error message on remote servers?
Solution 1:
That's because your locale in your local machine is set to German, which SSH forwards to and tries to use on the server, but your server does not have it installed.
You've got several options:
Generate the locale. Generate the German locale on the server with
sudo locale-gen de
.Stop forwarding locale from the client. Do not forward the locale environment variable from your local machine to the server. You can comment out the
SendEnv LANG LC_*
line in the local/etc/ssh/ssh_config
file.Stop accepting locale on the server. Do not accept the locale environment variable from your local machine to the server. You can comment out the
AcceptEnv LANG LC_*
line in the remote/etc/ssh/sshd_config
file.-
Set the server locale to English. Explicitly set the locale to English on the server. As an example, you can add the following lines to your remote
~/.bashrc
or~/.profile
files:export LANGUAGE="en" export LANG="C" export LC_MESSAGES="C"
If you don't have root access to the server, the Stop forwarding locale from the client option might be the best (and only) way to go.
Solution 2:
This can happen sometimes on fresh minimal/alternate installs or in other situations. The fix is pretty simple. Try these, in the following order, testing after each to see if the situation is fixed:
1. Reconfigure locales
-
sudo dpkg-reconfigure locales
- if that doesn't work,
2. Reinstall locale language-pack
-
sudo apt-get --reinstall install language-pack-de
- if that doesn't work,
3. Manually force locale settings (persistent)
sudo update-locale LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8
Solution 3:
Comment the line SendEnv LANG LC_*
in /etc/ssh/ssh_config
, so it should looks like:
#SendEnv LANG LC_*
Solution 4:
The Problem
By default, the ssh client command forwards locale-related environment variables to the SSH server. That's specified in /etc/ssh/ssh_config
on the client side:
Host *
SendEnv LANG LC_*
And by default, the SSH server happens to accept them (in /etc/ssh/sshd_config
on the server):
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
So, if there are locale-related environment variables in your shell, they will be populated to the SSH session on the server side.
Unfortunately, the SendEnv
option is cumulative. According to man 5 ssh_config
:
SendEnv
... Multiple environment variables may be separated
by whitespace or spread across multiple SendEnv directives. The
default is not to send any environment variables.
which means it can't be overridden.
The Solution
Sometimes it's impossible or unwise to change a system-wide configuration, especially on the server side. However, you may bypass it. And that's the side effect of the -F
option in ssh command. According to man ssh
:
-F configfile
Specifies an alternative per-user configuration file. If a con-
figuration file is given on the command line, the system-wide
configuration file (/etc/ssh/ssh_config) will be ignored. The
default for the per-user configuration file is ~/.ssh/config.
By default the per-user configuration file ~/.ssh/config
is used if it presents. But you can explicitly specify it on the command line to bypass /etc/ssh/ssh_config
:
$ touch ~/.ssh/config
$ ssh -F ~/.ssh/config your_user@your_host
It would be more convenient if you make an alias in ~/.bashrc
:
alias ssh="ssh -F ~/.ssh/config"
This way, the default SendEnv
directives in system-wide configuration are not effective, making no environment variables be sent to the SSH server by default.
Solution 5:
I had a similar issue. My solution was to comment the SendEnv
lines in /etc/ssh/ssh_config
(since these cannot be overriden), and to add the following entry in ~/.ssh/config
:
Host *,!<somehost>
SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
SendEnv XMODIFIERS
with <somehost>
being the hostname to which I didn't want to send any environment variable.