$LANG 对终端的影响

$LANG 对终端的影响

我试图学习变量在 gnome-terminal 中的行为方式$LANG(及其字符编码首选项)。我一直使用 iso8859-1 (latin1) 作为我的主要字符集,并且我的所有文件名都是这样编码的。

对于以下测试,我将创建ls -l文件名中包含西班牙语重音字符的目录:

情况1:

  • 为 ISO-8859-1 配置的 gnome 终端
  • LANG设置为“en_US-iso8859-1”
  • 结果:我正确地看到了所有文件

案例#2:

  • gnome 终端配置为 UTF-8
  • LANG设置为“en_US-iso8859-1”
  • 结果:我看到所有西班牙语字符都是垃圾字符。这是预期的,因为我更改了终端的字符编码

案例#3:

  • 为 ISO-8859-1 配置的 gnome 终端
  • LANG设置为“en_US-UTF-8”
  • 结果:我看到所有西班牙语字符都是垃圾字符。

为什么在最后一种情况下我看到乱码?不应该输出LS将文件名直接发送到 gnome-terminal 吗?由于 gnome-terminal 配置为 ISO-8859-1,我希望它们看起来是正确的。

有一瞬间我想,也许 bash 正在考虑我的$LANG变量并执行一些转换。然后我将终端切换为UTF-8,但我仍然看不到正确的字符。我什至将 ls 的输出通过管道传输到 xxd,令我惊讶的是,我仍然看到按原样编码的文件:ISO-8859-1。

总结:如果我的列表包含 ISO-8859-1 字符,并且我的终端仿真器配置为相同的字符编码:LANG否则设置时谁在进行转换?

感谢您的任何帮助,您可以提供。

克拉科尼亚

答案1

您的设置LANG必须与终端的设置匹配。更准确地说,您的(字符编码)设置LC_CTYPE必须与终端的编码匹配,其他区域设置不需要匹配。终端的编码通常由终端仿真器的选项指定,而不是由区域设置变量指定。它LC_CTYPE结合了两个指示:它告诉应用程序在终端上使用什么编码(输入和输出),并告诉应用程序对文件使用什么编码。在情况 2 和 3 中,您指定ls以与终端不同的编码显示输出,因此输出是乱码。

如果您在不同时间使用 UTF-8 和 latin-1 编码,请将终端配置为使用 UTF-8。这应该会导致它设置LC_CTYPE为指示 UTF-8 的值;不要覆盖此设置。 (如果终端模拟器未设置LC_CTYPE,请在 shell 启动文件或整个会话中覆盖它。)要在 UTF-8 终端中使用 latin-1 数据,请使用luit(包含在 X 实用程序套件中)。

LC_CTYPE=en_US.iso88591 luit

(您可以使用具有相同编码的任何其他区域设置,例如LC_CTYPE=es_ES.iso88591 luit。)

答案2

在情况 #2 和 #3 中,您混合了两种不同的编码 UTF-8 和 Latin-1。在情况 #1 中,您对两者都使用 Latin-1,所以不会有问题。

ls命令(以及所有其他运行良好的程序)使用 LANG 设置来确定编码

您可以混合两种不同的语言,但是您不应混合两种不同的编码

确保 LC_* 环境变量也使用与 LANG 变量相同的编码。

根据经验,您现在应该将系统配置为仅使用 UTF-8。

如果您必须编辑老式数据文件(例如 java 属性),您应该使用专门的编辑器(例如 java ide)或使用iconv“recode..”等工具确保编码。

答案3

这可能超出了您的需要,但是......

事实证明,在 RHEL5 中,甚至可能更早的版本中,许多手册页都出于某种不可预见的原因,被 ascii 化了。也就是说,原始手册页已从其本机字符集转换为 7 位 ASCII。无论您对 LC 和 LANG 做什么,手册页都会latin1生成一个实际上毫无用处的手册页。其中所有特殊(8 位)字符均已替换为 7 位占位符(通常为??)。我觉得这很搞笑。

utf8这些手册页的版本可能存在于特定于语言的目录中。诀窍是用他们的正确名字来询问他们。例如,latin1 实际上是iso_8859-1.如果你在上面做了一个手册页,并且你的 LANG 设置是正确的,你就会看到你所期望的;手册页位于特定于语言的子目录 ( en/man7/iso_8859-1.7) 中。但如果您出于某种原因询问iso-8859-1,您将得到 ASCII 版本。

相关内容