我在各个论坛上发现了很多问题,其中 Mac 用户抱怨locale
通过 SSH 登录 Linux 系统时出现错误,抱怨设置LC_CTYPE=UTF-8
不正确。
更详细地说,MacOS 上的 shell 似乎设置了这个值,然后(如果您在终端等中启用了该选项)LC_*
当您通过 SSH 登录时,您的本地变量将导出到远程系统。
Linux 坚持LC_CTYPE
需要将其设置为有效的区域设置(有时您可以localegen
在 Linux 系统上以管理员身份修复此问题),但UTF-8
首先它并不是一个区域设置。
我的基本的问题是,这是 MacOS 中的错误吗?或者 Linux 坚持要求将变量设置为完全指定的语言环境名称是错误的吗?
其次,为了能够争论哪一个是正确的以及为什么,这是在哪里指定的?
第三,这些 Mac 用户(包括我自己)是否可以或应该采取不同的做法?
明显的解决方法是放置类似的东西
LC_CTYPE=en_US.UTF-8
在您的 中,但这显然只能解决您的个人帐户的问题,并硬编码一个可能与您的其他设置.bash_profile
一致或不一致的值。locale
答案1
我没有详细讨论谁是“对谁错”——但同样对这个问题感到恼火。对此的一些解决方案:
- 服务器端:
- 更改/
AcceptEnv LC_*
禁用/etc/ssh/sshd
- 缺点:它将它们设置为系统默认值
- 编辑
.profile
- 缺点:单用户
- 编辑
/etc/bash*
或/etc/profile
- 缺点:更新中可能会逆转
- 更改/
- 客户端:
alias ssh="LC_CTYPE=\"${LANG}\" ssh"
.bashrc
//在.profile
任何地方- 缺点:单用户
.bashrc
与/.profile
...中的服务器端相同- 在终端中更改/添加设置
- 缺点:整个会话,无论是本地还是远程
所以,最后我最终在服务器上创建了mac-locale-fix.sh
这一/etc/profile.d
行(在我的例子中是 raspian):
[ "A${LC_CTYPE}" == "AUTF-8" ] && export LC_CTYPE="${LANG}"
希望这对其他人有帮助...
答案2
基本问题是
我的主要问题是,这是 MacOS 中的错误吗?或者 Linux 坚持要求将变量设置为完全指定的语言环境名称是错误的吗?
和POSIX环境变量页面显示了其他人认为 macOS 配置不正确的原因:
[XSI]如果区域设置值的形式为:
language[_territory][.codeset]
它指的是实现提供的语言环境,其中语言、区域和代码集的设置是实现定义的。
LC_COLLATE
,LC_CTYPE
,LC_MESSAGES
,LC_MONETARY
,LC_NUMERIC
, 和LC_TIME
定义为接受附加字段 @ 修饰符,它允许用户在单个类别中选择本地化数据的特定实例(例如,用于选择字典而不是数据的字符排序)。这些环境变量的语法定义为:[language[_territory][.codeset][@modifier]]
例如,如果用户想要用法语与系统交互,但需要对德语文本文件进行排序,则 LANG 和 LC_COLLATE 可以定义为:
LANG=Fr_FR LC_COLLATE=De_DE
这可以通过使用 @ 修饰符字段扩展到选择字典排序规则(例如);例如:
LC_COLLATE=De_DE@dict
实现可以支持其他格式。
如果实现无法识别区域设置值,则行为未指定。
也就是说,他们假设 POSIX 规定了语言环境设置的语法。粗心的读者可能会认为 POSIX 定义了环境变量的允许形式,以便代码集值是可选的,不能替代语言。但最后一个“可能”打开了一罐蠕虫,实际上祝福了这种解释上的差异。如果苹果想提供不完全遵循该模式的有效语言环境,它可以做任何它想做的事。
@tripleee 建议该页面语言环境提供了更好的信息,但这几乎完全是对区域设置定义的讨论,而不是提供指导互操作性(即 POSIX 表面上的目标)。
这两个页面都没有解决可用区域设置中的差异(例如“.utf8”与“.UTF-8”)。正如 POSIX 页面上所述,这些依赖于实现。这使得用户唯一的解决方案是自己确定本地和远程系统支持哪些区域设置,并(此处的 ssh 行为)确定如何“兼容”地在远程系统上设置这些设置。