“区分大小写是 Linux 文件系统的功能,而不是 Linux 操作系统”是什么意思?

Som*_*jee 15 filesystems bash zsh case-sensitivity

我刚读到下面这句话:

区分大小写是 Linux 文件系统的功能,而不是 Linux 操作系统。

我从这句话中推断出的是,如果我在 Linux 机器上,但我正在使用使用 Windows 文件系统格式化的设备,那么区分大小写就不是一回事了。

我尝试了以下方法来验证这一点:

$ ~/Documents: mkdir Test temp

$ ~/Documents: touch Test/a.txt temp/b.txt

$ ~/Documents: ls te*
b.txt
Run Code Online (Sandbox Code Playgroud)

它只列出了 temp目录中,这是预期的,因为我在 Linux 文件系统中。

当我导航到 Windows 文件系统时(注意:我使用的是 WSL2),我仍然得到相同的结果,但我希望它列出两个目录中的文件而忽略区分大小写。

$ /mnt/d: mkdir Test temp

$ /mnt/d: touch Test/a.txt temp/b.txt

$ /mnt/d: ls te*
b.txt
Run Code Online (Sandbox Code Playgroud)

我用 bash 和 zsh 都试过了。

我觉得它与 bash(或 zsh)有某种关系,因为我也读到 bash 强制区分大小写,即使在使用不区分大小写的文件系统时也是如此。

此测试适用于 Powershell,因此这意味着文件系统确实不区分大小写。

Sté*_*las 32

在这里,你正在运行:

ls te*
Run Code Online (Sandbox Code Playgroud)

使用名为globbing文件名生成(POSIX 中的路径名扩展)的shell功能,而不是 Linux 系统或 Linux 上使用的任何文件系统。

te*由 shell扩展与该模式匹配的文件列表。

为此,shell 向系统请求当前目录中的条目列表(通常使用readdir()C 库的函数,其底层将使用系统特定的系统调用(getdents()在 Linux 上)),然后将每个名称与图案。

除非您已将 shell 配置为不区分大小写(请参阅nocaseglobzsh 或 bash 中的选项)或使用 glob 运算符切换不区分大小写(如 中的(#i)扩展 glob 运算符zsh),te*否则只会扩展到名称为报告的readdir()开头为te,即使系统或下面的文件系统上的路径名解析不区分大小写或可以像 NTFS 一样。

  • 创建一个名为“TEST”的文件。然后尝试创建一个名为“test”的。您可以在本机 linux 文件系统上执行此操作,只有两个大小写不同的文件。但不是在 Windows 文件系统上。同样,创建“TEST”,然后执行“cat test”以查看内容 - 适用于 Windows, (19认同)
  • @pjc50 这对于 VFAT 是明确正确的,但对于 NTFS 则不正确,其中至少 `ntfs-3g` 在默认情况下使用 POSIX 命名空间,因此允许单个目录中的文件名仅因大小写而异。 (9认同)
  • 所以,基本上你的意思是说我没有正确测试该声明,你能告诉我如何验证该声明的真实性吗? (2认同)
  • @LarsH 基本上是的。但请注意,NTFS 本质上并不区分大小写:Windows 命名空间不区分大小写,并且 `ntfs-3g` 可以使用诸如 `ignore_case,windows_names` 之类的挂载选项。 (2认同)

Ste*_*itt 18

正如Vojtech 解释的那样,NTFS 区分大小写。在 FAT 文件系统上尝试它会起作用,但前提是您使用 case-folding 变体, msdos在 Linux 上(我不知道 WSL 上是否有等价物)。对于 FAT 的这种变体,文件名都是小写的,因此Test显示为test.

关于文件系统中的区分大小写,有许多方面需要考虑:

  • 文件系统本身是否存储案例信息;
  • 文件系统的预期用途是否考虑大小写;
  • 文件系统驱动程序或操作系统是否映射大小写,忽略大小写是否可以找到文件;
  • 如何映射案例。

历史FAT,如实现msdos,则介于前两者之间:从技术上讲,FAT可以存储情况,但在实践中没有使用这种方式,和MS-DOS和它的克隆折叠的情况下(这样readme.txtREADME.TXTReAdMe.TxT均有效访问方式README.TXT)。即使在保留大小写的文件系统(包括 VFAT 和 NTFS)上,Windows 也会保留这种行为。该msdos文件系统驱动程序处理此通过映射所有文件名称为小写,这是不完全正确,但产生一致的结果,避免问题Unix风格的工具和用户的期望。因此,在 Linux 上,使用msdos驱动程序挂载文件系统意味着README.TXT只能通过 访问readme.txt,而不能通过任何变体(包括上面显示的变体)访问。

你的报价来源于这样的事实是,Linux的内核本身并不特别在意,至少在表面上:一个能想象一个文件系统中open("README.TXT"),并open("ReAdMe.TxT")会打开相同的文件。事实上,XFS 可以通过这种方式配置,至少对于 ASCII 文件名(它保留大小写,但提供不区分大小写的查找)。然而,对于通用场景,事情很快变得更加复杂,多年来一直有很多讨论;参见例如Filesystems and case insensitiveCase-insensitive filesystem lookupsCase-insensitive ext4 on LWN。


Voj*_*fny 10

那是因为NTFS 也区分大小写,但 Windows 对用户隐藏了它。FAT 不区分大小写,您可以通过尝试在同一目录中创建testTest目录来检查:

$ ls
test
$ mkdir Test
mkdir: cannot create directory ‘Test’: File exists
$ mkdir TEST
mkdir: cannot create directory ‘TEST’: File exists
Run Code Online (Sandbox Code Playgroud)

它实际上多一点点比这更复杂,你的ls测试将因为它实际上是连与FAT工作情况下保持-它不会允许您创建Testtest目录,但它仍然使这两种情况之间的差异(和之间T*t*),所以ls t*testTemp两个不会列出内容。