$ LANG对终端的影响


11

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

对于以下测试,我将对ls -l文件名中带有西班牙语重音符号的目录执行以下操作:

情况1:

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

情况2:

  • 为UTF-8配置的gnome终端
  • 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否则设置时谁在进行转换?

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

克拉科尼亚

Answers:


5

您的设置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。)


感谢Gilles所作的精彩解释,特别是对于LC_CTYPE的两种指示的解释。
Craconia 2012年

回到我的最后一种情况:我以为,由于所有文件名都用latin1编码,加上我的最终输出设备(创建字形(终端)的设备)也配置了latin1,所以我希望能正确看到文件(无论LC_CTYPE如何)...
Craconia 2012年

我从来没有想到过ls要考虑LC_CTYPE(在这种情况下设置为UTF-8)并执行某种字符集验证:只要看到与字符集不兼容的内容,它就会吐出一个特定字符(例如“?”)。 ”)。我说“验证”是因为它不会像luit那样执行“转换”。像这样吗
Craconia 2012年

@Craconia在第三种情况下,ls将不可打印的字符替换为?。如果解释为UTF-8,大多数用latin-1编码的代表真实单词的字符串都具有不可打印的字符。
吉尔斯(Gillles)“所以-别再邪恶了”

5

在#2和#3的情况下,您要混合使用两种不同的编码UTF-8和Latin-1。在#1的情况下,您同时使用了Latin-1,因此没有问题。

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

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

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

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

如果您必须编辑老式的数据文件(例如,java属性),则应该使用专门的编辑器(例如,java ide),或确保使用诸如iconvrecode之类的工具进行编码。


谢谢。是的,我计划在不久的将来切换到UTF-8。得到了一堆文件名要转换以及许多其他文本文件。iconv和convmv进行救援...
Craconia 2012年

0

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

事实证明,在RHEL5中,可能由于某些gd的先入之故,许多手册页已经过某种形式的关联,这可能是在以前的版本中。也就是说,原始手册页已从其本机字符集转换为7位ASCII。无论您使用LC和LANG做什么,用于的手册页都会latin1产生实际上无用的手册页。其中的所有特殊(8位)字符都已替换为7位占位符(通常为??)。我觉得这很有趣。

但是utf8这些手册页的版本可能存在于特定于语言的目录中。诀窍是用正确的名字要求他们。例如,latin1实际上是iso_8859-1。如果在其上进行了手册页操作,并且您的LANG设置正确,那么您将看到期望的结果。手册页位于特定于语言的子目录(en/man7/iso_8859-1.7)中。但是,如果iso-8859-1由于某些原因而要求,则会得到ASCII版本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.