尝试了解包括 OS X 在内的各种 Linux 系统上的 UTF-8 区域设置可移植性(和 SSH)

尝试了解包括 OS X 在内的各种 Linux 系统上的 UTF-8 区域设置可移植性(和 SSH)

我花了很多时间ssh在各种机器上,这些机器各不相同(有些是嵌入式的,有些运行 Linux,有些运行 BSD,等等)。然而,在我自己的本地机器上,我使用 OS X,它当然有一个基于 BSD 的用户空间。我在这些机器上的语言环境设置为en_GB.UTF-8,这是可用选项之一:

% echo `sw_vers`
ProductName: Mac OS X ProductVersion: 10.8.2 BuildVersion: 12C60
% locale -a | grep -i 'en_gb.utf'
en_GB.UTF-8

我使用的几个功能更强大的 Linux 系统似乎有一个等效的选项,但我注意到在 Linux 上名称略有不同:

% lsb_release -d
Description: Debian GNU/Linux 6.0.3 (squeeze)
% locale -a | grep -i 'en_gb.utf' 
en_GB.utf8

这让我很疑惑:当我ssh从 Mac 进入 Linux 机器时,它会转发带有“UTF-8”后缀的所有LC_*变量,那么这台 Linux 机器是否理解了它所要求的内容?还是它只是回退到其他语言环境?

下面是我所指的一个例子:

% ssh -v odin
...
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LC_ALL = en_GB.UTF-8
debug1: Sending env LC_COLLATE = en_GB.UTF-8
debug1: Sending env LC_CTYPE = en_GB.UTF-8
debug1: Sending env LC_MESSAGES = en_GB.UTF-8
debug1: Sending env LC_MONETARY = en_GB.UTF-8
debug1: Sending env LC_NUMERIC = en_GB.UTF-8
debug1: Sending env LC_TIME = en_GB.UTF-8
debug1: Sending env LANG = en_GB.UTF-8
odin:~ % locale | tail -1  # locale is set to .UTF-8 without error...
LC_ALL=en_GB.UTF-8
odin:~ % locale -a | grep 'en_GB.UTF-8'  # ... even though .UTF-8 isn't an option
odin:~ % 

无论哪种情况,其行为背后的机制是什么,它是否依赖于任何特定设置(例如,我是否会在基于 BusyBox 的系统上看到与基于 GNU 的系统上相同的行为)?

答案1

这是一个有趣的问题,但我认为其中可能存在关于如何设置变量的误解。当启动安全 shell 会话 ( ssh remotehost) 时,另一端会实例化一个具有单独环境的新 shell。这是一种奇特的说法,即服务器启动了一个新 shell。新 shell 可能配置了与您原始本地 shell 相同的语言环境,也可能没有。

例如

哎呀:〜
$ echo `区域设置|grep LANG` :: `日期`
LANG=en_US.UTF-8 :: 2012 年 12 月 3 日星期一 07:04:00 CET

$ ssh flode
弗洛德:〜
$ echo `区域设置|grep LANG` :: `日期`
LANG=nb_NO.UTF-8 LANGUAGE=nb_NO.UTF-8 :: ma. 03. des. 06:59:33 +0100 2012

为了证明这一点,我通过在 ~/.bash_profile 文件中添加以下几行,在远程 shell 上将语言环境设置为挪威语:

export     LANG=nb_NO.UTF-8
export LANGUAGE=nb_NO.UTF-8
export   LC_ALL=nb_NO.UTF-8

同样,你必须在远程 shell执行相同的操作。当然,其他 shell 会读取不同的启动文件,例如 Z shell 的 ~/.zprofile。

我怀疑的误解在于本地变量(设置)绝不会转发。远程 shell 有自己的设置。为了列出远程主机上可用的语言,无论是简约的 BusyBox shell 还是成熟的 GNU OS,请使用locale带有-a开关的命令(如问题中所述)。任何打印的行都可以用作该环境的区域设置。

至于第一个问题,任何 shell 启动时的默认语言环境通常都配置在 /etc/profile 等中心位置。大多数登录 shell 在启动时都会读取此文件。

答案2

对于以下命令,不同系统上 UTF-8 支持的名称是否也略有不同?

LC_ALL='' locale charmap  # UTF-8 (on Mac OS X 10.6.8)

如果你遇到奇怪的语言环境相关问题,可以通过LC_*注释掉 SSH 客户端来告诉它不要发送这些变量SendEnv LANG LC_*/etc/ssh_config例如,修复 Mac OS X Lion 的 SSH UTF-8 问题OS X Lion 中的终端:无法在远程机器上写入 åäö)。

另一种解决方法是这样的:

# from: http://mod16.org/hurfdurf/?p=189
tjac wrote:
Actually the real problem that's causing this is that Mac OS 10.7 sets totally 
non-standard locale values, at least when you tweak some of the formats in
SysPrefs/Language&Text as I did.

If you type "locale" on your Mac terminal you should see pretty much the same as on 
other Unices (e.g. lots of en_US.UTF-8s if you prefer US English), but you don't. 
If these garbled settings get transferred to other Unix hosts by the SendEnv option 
they naturally do not know what's going on.

So if you want to fix it cleanly to allow for sshing to all kinds of remote hosts,
including those with older character sets, put the following lines in your 
~/.bash_profile on your Mac client machine.

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

Monday, September 12, 2011 at 22:54 #

相关内容