As variáveis ​​de localidade não têm efeito no shell remoto (perl: warning: falha na configuração da localidade).

89

Eu tenho uma nova instalação do ubuntu 12.04. Quando me conecto ao meu servidor remoto, recebo erros como este:

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

Não tenho esse problema quando me conecto a partir de uma instalação mais antiga do ubuntu. Isso é resultado da minha instalação do ubuntu 12.04, LANG e LANGUAGE estão definidas

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

Alguém sabe o que mudou no ubuntu para receber essa mensagem de erro em servidores remotos?

Janning
fonte

Respostas:

167

Isso ocorre porque o local em sua máquina local está definido como alemão, que o SSH encaminha e tenta usar no servidor, mas o servidor não o instala.

Você tem várias opções:

  • Gere o código do idioma . Gere o código de idioma alemão no servidor com sudo locale-gen de.

  • Pare de encaminhar a localidade do cliente . Não encaminhe a variável de ambiente locale da sua máquina local para o servidor. Você pode comentar a SendEnv LANG LC_*linha no arquivo local /etc/ssh/ssh_config .

  • Pare de aceitar a localidade no servidor . Não aceite a variável de ambiente locale da sua máquina local para o servidor. Você pode comentar a AcceptEnv LANG LC_*linha no arquivo remoto /etc/ssh/sshd_config .

  • Defina o código do idioma do servidor para inglês . Defina explicitamente o código do idioma para inglês no servidor. Como exemplo, você pode adicionar as seguintes linhas ao seu controle remoto ~/.bashrcou ~/.profilearquivos:

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

Se você não tiver acesso root ao servidor, a opção Interromper o encaminhamento do código do idioma a partir do cliente pode ser o melhor (e único) caminho a percorrer.

David Planella
fonte
2
Hah! Perdi totalmente o fato de ele listar as configurações de local do cliente ! Grande trabalho ...
ish
10
Decidi "Parar de encaminhar a localidade do cliente". Funciona bem. Para referência futura: você não pode substituir as configurações do SendEnv em / etc / ssh / ssh_config no seu local ~ / .ssh / config. Veja bugzilla.mindrot.org/show_bug.cgi?id=1285
Jan
3
Combinado com bugs.php.net/bug.php?id=18556 , o envio de localidades pelo SSH pode causar problemas reais (e na verdade para mim), consulte bugzilla.mindrot.org/show_bug.cgi?id=1285#c9 .. .
Halil Özgür
1
No meu caso, definir o código de idioma ~/.profileresolveu meu problema. Obrigado.
Francisco
Se o servidor não tem locale alemão, por que é aceitável para ele para substituir o valor solicitado pelo usuário LANGcom outra coisa ..?
Mikhail T.
26

Às vezes, isso pode acontecer em instalações mínimas / alternativas novas ou em outras situações. A correção é bem simples. Tente estes, na seguinte ordem, testando após cada um para verificar se a situação foi corrigida:

1. Reconfigure as localidades

  • sudo dpkg-reconfigure locales
    • se isso não funcionar,

2. Reinstale o pacote de idiomas da localidade

  • sudo apt-get --reinstall install language-pack-de
    • se isso não funcionar,

3. Forçar manualmente as configurações de local (persistente)

  • sudo update-locale LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8
ish
fonte
Estou com um problema na JVM e também estou tentando definir o código do idioma do sistema na versão 12.04. O único problema é que não consigo definir o LC_ALL, não importa o que eu tente, os códigos de idioma ainda o mostram vazio.
Escuro Star1
15

Comente a linha SendEnv LANG LC_*em /etc/ssh/ssh_config, por isso deve se parece com:

#SendEnv LANG LC_*
Zhengpeng Hou
fonte
10

O problema

Por padrão, o comando ssh client encaminha variáveis ​​de ambiente relacionadas ao código do idioma para o servidor SSH. Isso é especificado no /etc/ssh/ssh_configlado do cliente:

Host *
    SendEnv LANG LC_*

E, por padrão, o servidor SSH os aceita (no /etc/ssh/sshd_configservidor):

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

Portanto, se houver variáveis ​​de ambiente relacionadas ao código do idioma no seu shell, elas serão preenchidas na sessão SSH no lado do servidor.

Infelizmente, a SendEnvopção é cumulativa . De acordo com 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.

o que significa que não pode ser substituído .

A solução

Às vezes, é impossível ou imprudente alterar uma configuração em todo o sistema, especialmente no lado do servidor. No entanto, você pode ignorá- lo. E esse é o efeito colateral da -Fopção no comando ssh. De acordo com 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.

Por padrão, o arquivo de configuração por usuário ~/.ssh/configé usado se apresentar. Mas você pode especificá-lo explicitamente na linha de comando para ignorar /etc/ssh/ssh_config:

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

Seria mais conveniente se você criar um alias em ~/.bashrc:

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

Dessa forma, as SendEnvdiretivas padrão na configuração de todo o sistema não são eficazes, tornando nenhuma variável de ambiente enviada ao servidor SSH por padrão.

Rockallite
fonte
2
Lembre-se de que o arquivo de configuração do sistema em / etc / ssh / config pode conter linhas adicionais que você deseja manter na configuração do usuário. Você precisará copiá-los para o arquivo de configuração do usuário em ~ / .ssh / config para manter essas configurações.
Steven Maude
4

Eu tive uma questão semelhante. Minha solução foi comentar as SendEnvlinhas /etc/ssh/ssh_config(já que elas não podem ser substituídas) e adicionar a seguinte entrada em ~/.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    

com <somehost>sendo o nome do host para o qual eu não quero enviar qualquer variável de ambiente.

Gwendal
fonte