语言环境变量在远程 shell 中不起作用(perl:警告:设置语言环境失败。)

Jan*_*ing 98 ssh locale

我有一个全新的 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.
...
Run Code Online (Sandbox Code Playgroud)

当我从较旧的 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=
Run Code Online (Sandbox Code Playgroud)

有人知道 ubuntu 发生了什么变化以在远程服务器上收到此错误消息吗?

Dav*_*lla 180

那是因为您在本地机器上的语言环境设置为德语,SSH 转发到并尝试在服务器上使用,但您的服务器没有安装它。

你有几个选择:

  • 生成语言环境。在服务器上生成德语语言环境sudo locale-gen de

  • 停止从客户端转发语言环境。不要将本地环境变量从本地机器转发到服务器。您可以注释掉本地文件中的SendEnv LANG LC_*行。 /etc/ssh/ssh_config

  • 停止接受服务器上的语言环境。不要接受从本地机器到服务器的语言环境环境变量。您可以注释掉远程文件中的AcceptEnv LANG LC_*行。 /etc/ssh/sshd_config

  • 将服务器区域设置为 English。在服务器上将语言环境显式设置为英语。例如,您可以将以下行添加到远程~/.bashrc~/.profile文件中:

    export LANGUAGE="en"
    export LANG="C"
    export LC_MESSAGES="C"
    
    Run Code Online (Sandbox Code Playgroud)

如果您没有服务器的 root 访问权限,则停止从客户端转发区域设置选项可能是最好的(也是唯一的)方法。

  • 我决定“停止从客户端转发语言环境”。工作正常。供将来参考:您不能从本地 ~/.ssh/config 中的 /etc/ssh/ssh_config 覆盖 SendEnv 设置。见 https://bugzilla.mindrot.org/show_bug.cgi?id=1285 (12认同)
  • 结合 https://bugs.php.net/bug.php?id=18556,SSH 的语言环境发送会导致真正的问题(实际上是对我造成的),请参阅 https://bugzilla.mindrot.org/show_bug.cgi ?id=1285#c9 ... (4认同)
  • 哈!我完全错过了他列出*客户*语言环境设置的事实!很好... (3认同)

ish*_*ish 29

这有时会发生在新的最小/替代安装或其他情况下。修复非常简单。按以下顺序尝试这些,在每个之后进行测试以查看情况是否已修复:

1. 重新配置语言环境

  • sudo dpkg-reconfigure locales
    • 如果这不起作用,

2.重新安装locale语言包

  • sudo apt-get --reinstall install language-pack-de
    • 如果这不起作用,

3.手动强制区域设置(持久)

  • sudo update-locale LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8


小智 16

注释行SendEnv LANG LC_*/etc/ssh/ssh_config,所以它应该看起来像:

#SendEnv LANG LC_*
Run Code Online (Sandbox Code Playgroud)


Roc*_*ite 14

问题

默认情况下,ssh client 命令将与语言环境相关的环境变量转发到 SSH 服务器。这是在/etc/ssh/ssh_config客户端指定的:

Host *
    SendEnv LANG LC_*
Run Code Online (Sandbox Code Playgroud)

默认情况下,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
Run Code Online (Sandbox Code Playgroud)

因此,如果您的 shell 中有与语言环境相关的环境变量,它们将被填充到服务器端的 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.
Run Code Online (Sandbox Code Playgroud)

这意味着它不能被覆盖

解决方案

有时更改系统范围的配置是不可能或不明智的,尤其是在服务器端。但是,您可以绕过它。这就是-Fssh 命令中选项的副作用。根据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.
Run Code Online (Sandbox Code Playgroud)

默认情况下,~/.ssh/config如果存在每用户配置文件,则使用它。但是您可以在命令行上明确指定它以绕过/etc/ssh/ssh_config

$ touch ~/.ssh/config
$ ssh -F ~/.ssh/config your_user@your_host
Run Code Online (Sandbox Code Playgroud)

如果您在~/.bashrc以下位置创建别名会更方便:

alias ssh="ssh -F ~/.ssh/config"
Run Code Online (Sandbox Code Playgroud)

这样,SendEnv系统范围配置中的默认指令无效,默认情况下不会将环境变量发送到 SSH 服务器。

  • 请记住,/etc/ssh/config 中的系统配置文件可能包含您希望在用户配置中保留的附加行。您必须将它们复制到 ~/.ssh/config 中的用户配置文件以保留这些设置。 (3认同)

小智 6

我有类似的问题。我的解决方案是注释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    
Run Code Online (Sandbox Code Playgroud)

作为我不想发送任何环境变量的<somehost>主机名。