在Mac OS X工作桌面上,ssh登陆到通过Vagrant创建的centos 系统中,发现每次都提示

-bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory

我在 centos 虚拟机的操作系统 /etc/profile 中添加了

LC_CTYPE=en_US.UTF-8
export LC_CTYPE

但是报错依旧是一样的。奇怪,这个不是远程Liunx操作系统的环境变量么?

这个告警或错误是OpenSSH服务器和OS X ssh终端客户程序共同导致的问题,可以通过几种方式来修复。

理解LC_*环境变量

在远程服务器上执行下述命令来显示所有Glibc所支持的locales

locale -a

然后在本地的Mac主机上执行显示本地环境的命令

printenv
echo "$LC_CTYPE"

可以看到输出显示是

UTF-8

以上命令会显示本地系统的国家和语言名字,以及locale使用的字符集。本地ssh客户端将发送LC_*环境变量给远程的sshd服务器。也就是说,SSH将尝试在远程服务器上设置和本地OSX系统一样的LC_*环境变量。这就导致了ssh登陆远程Linux服务器出现告警:

-bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory

修正LC_CTYPE

方法一:在ssh客户端关闭启动时设置本地环境变量

这个方法不好,因为会导致终端无法显示本地中文文件名

如果你在OS X系统中使用Terminal app

Terminal > Preferences > 选择中断类型例如Basic (default) > Advanced tab

设置LC_CTYPE

确保取消了Set locale environment variables on startup,然后关闭ssh会话再次启动Terminal程序,然后ssh到远程服务器就不会出现这个错误提示。

方法二:禁止OpenSSH客户端从OS X/Linux/Unix桌面发送LC_*变量

修改/etc/ssh/ssh_config或者/etc/ssh/ssh_config文件,删除掉或者注释掉以下配置内容

#SendEnv LANG LC_*

检查了Mac OS X的/etc/ssh/ssh_config配置,其中默认有如下配置

# Site-wide defaults for some commonly used options.  For a comprehensive
# list of available options, their meanings and defaults, please see the
# ssh_config(5) man page.

# Apple:
 Host *
   SendEnv LANG LC_*
#   AskPassGUI yes


#   ForwardAgent no
#   ForwardX11 no
#   RhostsRSAAuthentication no
#   RSAAuthentication yes
#   PasswordAuthentication yes
#   HostbasedAuthentication no
#   GSSAPIAuthentication no
#   GSSAPIDelegateCredentials no
......

采用注释掉 /etc/ssh/ssh_config 中的 SendEnv LANG LC_* 配置行

这个方法比较合适

方法三:在远程服务器上安装要求的locale

可以使用localedef命令安装需要的locale,或者考虑在本地/远程系统中选择另外的locale

localedef -i en_US -f UTF-8 en_US.UTF-8

参考