Переменные локали не действуют в удаленной оболочке (perl: warning: Ошибка настройки локали.)

89

У меня свежая установка Ubuntu 12.04. Когда я подключаюсь к своему удаленному серверу, я получаю такие ошибки:

~$ 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.
...

У меня нет этой проблемы, когда я подключаюсь из более старой установки Ubuntu. Это вывод из моей установки Ubuntu 12.04, LANG и LANGUAGE установлены

$ 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=

Кто-нибудь знает, что изменилось в Ubuntu, чтобы получить это сообщение об ошибке на удаленных серверах?

Janning
источник

Ответы:

167

Это потому, что для вашей локали на вашем локальном компьютере задан немецкий язык, который SSH пересылает и пытается использовать на сервере, но на вашем сервере он не установлен.

У вас есть несколько вариантов:

  • Генерация локали . Сгенерируйте немецкую локаль на сервере с помощью sudo locale-gen de.

  • Прекратите пересылку локали от клиента . Не пересылайте переменную среды локали с вашего локального компьютера на сервер. Вы можете закомментировать SendEnv LANG LC_*строку в локальном /etc/ssh/ssh_config файле.

  • Прекратите принимать локаль на сервере . Не принимайте переменную окружения локали с вашего локального компьютера на сервер. Вы можете закомментировать AcceptEnv LANG LC_*строку в удаленном /etc/ssh/sshd_config файле.

  • Установите языковой стандарт сервера на английский . Явно установите локаль на английский на сервере. Например, вы можете добавить следующие строки на ваш пульт ~/.bashrcили ~/.profileфайлы:

    export LANGUAGE="en"
    export LANG="C"
    export LC_MESSAGES="C"
    

Если у вас нет корневого доступа к серверу, вариант Остановить переадресацию с клиента может быть лучшим (и единственным) способом.

оборота Дэвид Планелла
источник
2
Хах! Я полностью упустил тот факт, что он перечислил настройки языка клиента ! Большая работа ...
иш
10
Я решил «Прекратить пересылку локали от клиента». Работает отлично. Для дальнейшего использования: вы не можете переопределить настройки SendEnv из / etc / ssh / ssh_config в вашей локальной ~ / .ssh / config. См bugzilla.mindrot.org/show_bug.cgi?id=1285
Janning
3
В сочетании с bugs.php.net/bug.php?id=18556 отправка локалей по SSH может привести к реальным проблемам (и на самом деле для меня), см. Bugzilla.mindrot.org/show_bug.cgi?id=1285#c9 .. .
Халил Özgür
1
В моём случае установка локали в ~/.profileразрешила мою проблему. Благодарю.
Франциско
Если у сервера нет немецкой локали, почему допустимо перезаписывать запрашиваемое пользователем значение LANGчего-то еще? ..
Михаил Т.
26

Это может происходить иногда на новых минимальных / альтернативных установках или в других ситуациях. Исправление довольно простое. Попробуйте выполнить следующее тестирование в следующем порядке, чтобы убедиться, что ситуация исправлена:

1. Переконфигурируйте локали

  • sudo dpkg-reconfigure locales
    • если это не сработает,

2. Переустановите языковой пакет локали

  • sudo apt-get --reinstall install language-pack-de
    • если это не сработает,

3. Вручную форсировать настройки локали (постоянные)

  • sudo update-locale LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8
иш
источник
У меня проблема с JVM, и я пытаюсь установить системную локаль в 12.04. Единственная проблема в том, что я не могу установить LC_ALL независимо от того, что я пытаюсь, локали все еще показывают его как пустое.
Dark Star1
15

Комментарий линии SendEnv LANG LC_*в /etc/ssh/ssh_config, так это должно выглядеть так:

#SendEnv LANG LC_*
Чжэнпэн Хоу
источник
10

Проблема

По умолчанию команда клиента ssh пересылает переменные среды, связанные с языковым стандартом, на сервер SSH. Это указано /etc/ssh/ssh_configна стороне клиента:

Host *
    SendEnv LANG LC_*

И по умолчанию сервер SSH принимает их ( /etc/ssh/sshd_configна сервере):

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

Таким образом, если в вашей оболочке есть переменные среды, связанные с локалью, они будут заполнены в сеансе SSH на стороне сервера.

К сожалению, SendEnvвариант является накопительным . По словам 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.

что означает, что это не может быть отменено .

Решение

Иногда невозможно или неразумно изменить общесистемную конфигурацию, особенно на стороне сервера. Тем не менее, вы можете обойти это. И это побочный эффект -Fопции в команде ssh. По словам 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.

По умолчанию используется файл конфигурации для каждого пользователя, ~/.ssh/configесли он присутствует. Но вы можете явно указать это в командной строке, чтобы обойти /etc/ssh/ssh_config:

$ touch ~/.ssh/config
$ ssh -F ~/.ssh/config your_user@your_host

Было бы удобнее, если вы сделаете псевдоним в ~/.bashrc:

alias ssh="ssh -F ~/.ssh/config"

Таким образом, SendEnvдирективы по умолчанию в общесистемной конфигурации не эффективны, поэтому по умолчанию никакие переменные среды не отправляются на сервер SSH.

Rockallite
источник
2
Помните, что файл конфигурации системы в / etc / ssh / config может содержать дополнительные строки, которые вы хотите сохранить в своей пользовательской конфигурации. Вам нужно будет скопировать их в свой пользовательский конфигурационный файл в ~ / .ssh / config, чтобы сохранить эти настройки.
Стивен Мод
4

У меня была похожая проблема. Мое решение состояло в том, чтобы закомментировать SendEnvстроки /etc/ssh/ssh_config(поскольку они не могут быть переопределены) и добавить следующую запись в ~/.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    

с <somehost>именем хоста, на который я не хотел отправлять переменные окружения.

Gwendal
источник