Linux shell和文件系统如何识别Unicode?

Mar*_*eck 3 linux unicode shell utf-8

我知道Linux文件系统将文件名存储为字节序列,这意味着与Unicode编码无关.

但是,除了UTF-8或增强型UTF-8之外的编码很可能使用0字节作为可以出现在文件名中的Unicode字符的多字节表示的一部分.在Linux文件系统C代码中的任何地方都可以使用0字节终止字符串.那么Linux文件系统如何支持Unicode呢?是否假设所有创建文件名的应用程序仅使用UTF-8?但事实并非如此,是吗?

类似地,shell(例如bash)*在模式中使用以匹配任意数量的文件名字符.我可以在shell C代码中看到它只是使用ASCII字节*并逐字节地去分配匹配.适用于UTF-8编码的名称,因为它具有以下属性:如果您接受字符串的字节表示,然后匹配起始的一些字节*,并将其余字符与另一个字符串匹配,那么开头的字节实际上匹配一串完整的字符,而不仅仅是字节.

但其他编码没有那个属性,是吗?那么,shell再次假设为UTF-8吗?

zwo*_*wol 6

确实,UTF-16和其他"宽字符"编码不能用于Linux中的路径名(也不能用于任何其他符合POSIX的操作系统).

这是不是在原则上,任何人都假定UTF-8真实的,尽管这可能会作为其他编码死光了要在未来实现.Unix风格的程序假设是与ASCII兼容的编码.具有这些属性的任何编码都是ASCII兼容的:

  • 编码的基本单位是字节,而不是更大的实体.某些字符可能被编码为字节序列,但必须至少有127个字符仅使用单个字节进行编码,即:
  • 由ASCII定义的字符(现在,这些最好描述为Unicode代码点U + 000000到U + 00007F,包括在内)被编码为单个字节,其值等于其Unicode代码点.
  • 相反,值为0x00到0x7F的字节必须始终解码为ASCII定义的字符,而不管周围的上下文如何.(例如,字符串0x81 0x2F必须解码为两个字符,无论0x81解码到哪个/.)

UTF-8与ASCII兼容,但所有ISO-8859-n页面,EUC编码以及许多其他页面也是如此.

有些计划可能还需要额外的财产:

  • 字符串的编码(作为字节序列)从不是正确的前缀,也不是任何其他字符编码的正确后缀.

UTF-8有这个属性,但(我认为)EUC-JP没有.

也是许多"Unix风格"的方案保留码点U + 000000(NUL)用作一个字符串结束的情况下.这在技术上不是编码的约束,而是对文本本身的约束.(字节 0x00不出现在字符串中间的密切相关的要求是这样的结果加上要求0x00映射到U + 000000而不管周围的上下文.)