网站搜索

为什么 exFAT 上的仅大小写重命名会失败(以及如何修复)


将 File 重命名为 file 在 ext4 上可以正常工作,但在 exFAT 文件系统上会失败。在本指南中,我们将了解为什么 exFAT 会将这两个名称视为相同,它的 Unicode 大写表是如何工作的,以及执行 仅大小写重命名 的最简单方法。

exFAT 不允许你仅更改字母大小写

你打开一个终端并运行一个简单的命令:

mv Desktops desktops

你没有重命名文件夹,而是出现这个错误:

mv: cannot move 'Desktops' to a subdirectory of itself, 'desktops/Desktops'

为什么你不能在 exFAT 上把 Desktops 重命名为 desktops

起初,这个错误看起来很令人困惑。毕竟,你只是想把一个大写字母改成小写字母。

好消息是 mv 命令没有问题。真正的原因是你的文件系统。

让我们看看为什么会发生这种情况,exFAT 在底层是如何工作的,以及为什么这个错误实际上是合理的。

什么是 exFAT?

exFAT(扩展文件分配表) 是微软为闪存驱动器、SD 卡和外部存储设备设计的文件系统。

它支持比FAT32更大的文件和分区,这使其成为USB闪存驱动器、便携式SSD和存储卡的热门选择。如今,Windows、macOS和Linux都支持exFAT,这使其在不同操作系统之间移动存储设备时成为最容易使用的文件系统之一。

然而,exFAT 也遵循一些 Windows 风格的文件名规则。其中一条规则是,在比较文件名时忽略大小写字母。这个设计选择正是导致将 Desktops 改为 desktops 的行为与大多数 Linux 文件系统不同的原因。

你什么时候可能会看到这个?

当使用USB闪存驱动器、便携式SSD、SD卡或格式化为exFAT的存储卡时,你最常会遇到这种情况。

如果你在 Linux 系统的内部驱动器上工作,你可能正在使用不同的文件系统,例如 ext4,所以仅更改大小写的重命名通常能够按预期工作。

为什么会发生这种情况:简短的回答

如果您的驱动器使用exFAT,文件系统会将这些名称视为相同:

  • Desktops
  • desktops
  • DESKTOPS

换句话说,exFAT 在比较文件名时会忽略大小写字母。然而,它仍然会记住你使用的大小写,并按你输入的方式显示文件名。

这种行为被称为不区分大小写但保留大小写。

因此,仅仅改变字母的大小写并不像看起来那么简单。

为什么 ext4 可以重命名而 exFAT 不行

许多人认为 ext4 的重命名功能比 exFAT 更好。

它没有。

两种文件系统都支持重命名文件和文件夹。区别在于它们如何查找文件名。

在 mv 重命名任何内容之前,它会向文件系统提出一个简单的问题:

“是否已存在具有目标名称的文件或文件夹?”

答案完全取决于文件系统如何比较名称。

ext4 如何查找名称

可以将目录视为文件名的列表。当 ext4 搜索该列表时,它会将每个文件名与存储的内容逐字比较。

这意味着这是三个完全不同的名字:

Desktops
desktops
DESKTOPS

假设你的目录包含:

Desktops

现在你跑:

mv Desktops desktops

ext4 搜索与 desktops 完全匹配的文件名。

它没有找到一个。

从 ext4 的角度来看:

  • 桌面 存在。
  • desktops 不行。

由于没有冲突,文件系统只需用新名称更新目录项。

重命名在一步中成功。

exFAT 如何查找名称

exFAT 的工作方式非常不同。

它不是直接比较文件名,而是先将两个名字转换成一种通用形式再进行比较。

为此,exFAT 使用一种存储在文件系统内部的特殊数据结构,称为大写表。

与 ext4 不同,这个比较 不 使用原始字母。相反,两个名称都会先进行标准化。

什么是大写表?

大写表是 exFAT 文件系统定义的独特结构之一。

它包含将小写字符转换为大写等效字符的 Unicode 映射。

例如,该表包含如下映射:

a → A
b → B
d → D
é → É
δ → Δ

该表包含数千个 Unicode 映射,而不仅仅是英文字母。

因为映射存在于文件系统中,每个操作系统都可以使用完全相同的规则来比较文件名。

exFAT 如何比较文件名

想象你的目录包含这个文件夹:

Desktops

现在你跑:

mv Desktops desktops

在比较名称之前,exFAT 会使用大写表转换两个名称。

从概念上看,它是这样的:

Stored name:
Desktops
    ↓
DESKTOPS
New name:
desktops
    ↓
DESKTOPS

转换后,两个名字变为:

DESKTOPS

从 exFAT 的角度来看,它们是相同的。

所以当 mv 问时,

“desktops 已经存在吗?”

文件系统回答,

“是的。”

因为归一化之后,它确实会这样。

为什么存在大写表

你可能会想,为什么 exFAT 存储一个表,而不是自己直接转换字母。

答案是 Unicode。

许多语言包含比英文字母复杂得多的大写和小写字符。

exFAT 并没有要求每个操作系统永远硬编码相同的 Unicode 转换规则,而是将转换表存储在文件系统内。

这提供了一些优势。

首先,每个操作系统都使用相同的规则比较文件名。

其次,Unicode 映射可以在不重新设计文件系统的情况下演变。

最终,不同的操作系统仍然彼此兼容,因为它们都使用存储在磁盘上的相同转换表。

这是一个出人意料地优雅的设计。

为什么 exFAT 仍然保留大小写

虽然 exFAT 在比较时忽略字母大小写,但它仍然会将原始文件名按你输入的方式完整存储。

假设你创建了:

MyHolidayPhotos

该目录将显示:

MyHolidayPhotos

它不会改变大小写。

然而,在搜索该文件时,这些名称都匹配:

MyHolidayPhotos
myholidayphotos
MYHOLIDAYPHOTOS

这就是为什么 exFAT 被描述为保留大小写但不区分大小写的原因。

为什么这个错误看起来如此奇怪

现在让我们回到原来的命令。

mv Desktops desktops

在重命名前,mv 会检查目标是否已存在。

在 exFAT 上,文件系统报告 desktops 已经存在,因为它在比较名称时不考虑字母大小写。

在那时,mv 假设你想将 Desktops 目录移动到一个名为 desktops 的现有目录中。

从概念上讲,它看到的是这样的东西:

Desktops/
└── Desktops/

那会在自身内部创建一个目录。

由于这是不可能的,mv 停止并打印:

mv: cannot move 'Desktops' to a subdirectory of itself, 'desktops/Desktops'

该命令并不混乱。它只是信任文件系统告诉它的信息。

错误消息来自 mv,但行为来自 exFAT 对文件名的比较方式。

重命名仅字母大小写不同的 exFAT 文件和文件夹

最简单的解决方案是使用临时名称。

mv Desktops temp-desktops
mv temp-desktops desktops

临时名称消除了冲突。一旦原始名称不再存在,第二次重命名就会成功。

在 exFAT 上使用临时名称重命名文件

尽管这需要两个命令,但它是在 exFAT 上最简单且最可靠的方法。

更多例子

示例 1:照片文件夹

假设你的外部 SSD 包含:

photos2026

你想要:

Photos2026

如果你尝试像下面这样使用 mv 命令重命名它:

mv photos2026 Photos2026

它会失败。

相反,可以像下面这样使用临时名称重命名 exFAT 上的文件:

mv photos2026 Photos-temp
mv Photos-temp Photos2026

示例 2:音乐文件夹

当前文件夹:

RockMusic

期望的名字:

rockmusic

再次,使用一个中间名称。

mv RockMusic rock-temp
mv rock-temp rockmusic

同样的技巧也适用于文件。

这会发生在每个 Linux 文件系统上吗?

不。大多数 Linux 文件系统默认是区分大小写的。

例如,ext4 允许所有这些存在于同一目录中:

Project
project
PROJECT

因此这可以在不采取任何额外步骤的情况下工作:

mv Project project

Btrfs 和 XFS 通常也是如此。

哪些文件系统忽略字母大小写?

文件系统默认区分大小写吗?
ext4是
Btrfs是
XFS是
exFAT不
FAT32不
NTFS(典型的 Linux 挂载)通常不

如果你主要使用外部 USB 驱动器,你可能会遇到这种情况,因为许多便携式驱动器都是 exFAT 格式的。

如何检查你的文件系统

如果你不确定你的驱动器使用的是哪种文件系统,请运行:

df -T .

或者:

findmnt -T .

或者,如果你只想要文件系统类型:

findmnt -n -o FSTYPE -T .

如果输出显示:

exfat

那么这种行为是预期的。

你可以在以下教程中找到更多检查文件系统类型的方法:

  • 如何在Linux中查找文件系统类型

关键要点

仅将大写字母改为小写看起来像是简单的重命名。

但是,exFAT 与大多数 Linux 文件系统比较文件名的方式不同。

记住以下要点:

  • exFAT 在比较文件名时不考虑字母大小写。
  • 它使用内置的 Unicode 大写表 来完成此操作。
  • Desktops、desktops 和 DESKTOPS 都被视为相同的名称。
  • mv 在检查目标是否已存在时信任文件系统。
  • 因此,仅更改大小写的重命名通常在 exFAT 上会失败。
  • 通过临时名称重命名是最简单、最可靠的解决方案。

一旦你了解了 exFAT 是如何查找文件名的,这个错误信息就不再神秘了。它只是文件系统设计方式的结果。

无需 exFAT 驱动器即可自行尝试(可选)

本部分是 可选 的。你 不需要 外接 USB 驱动器或 SSD 来跟随操作。相反,你可以使用 Linux 环回设备 在磁盘镜像中创建一个临时 exFAT 文件系统。

循环设备让 Linux 将普通文件当作真实的块设备(例如 USB 驱动器或 SSD)来处理。这使得在不修改任何物理存储的情况下进行实验变得安全。当你完成后,只需卸载文件系统并删除映像文件。

创建测试环境

首先,安装所需的工具:

sudo apt update
sudo apt install exfatprogs

接下来,创建一个 100 MiB 的磁盘映像:

truncate -s 100M exfat_test.img

将映像附加到空闲的环回设备,并将分配的设备名称保存到一个 shell 变量中:

LOOP=$(sudo losetup --find --show exfat_test.img)

创建 exFAT 文件系统:

sudo mkfs.exfat "$LOOP"

创建一个挂载点并挂载文件系统:

mkdir mnt_exfat
sudo mount -t exfat \
  -o uid=$(id -u),gid=$(id -g) \
  "$LOOP" mnt_exfat

uid 和 gid 挂载选项使您的用户成为挂载的 exFAT 文件系统的所有者。这让您可以在不使用 sudo 的情况下创建、重命名和删除文件,从而使本指南中的示例更容易理解。

创建 exFAT 测试环境

测试命令

切换到已挂载的文件系统:

cd mnt_exfat

创建一个测试目录:

mkdir Desktops

现在试试本文中讨论的命令:

mv Desktops desktops

你应该会看到与在实际 exFAT 格式化的 USB 驱动器或 SSD 上相同的行为。

仅大小写重命名在 exFAT 上失败.png

清理

完成后,卸载文件系统,分离循环设备,并删除临时文件:

cd ..
sudo umount mnt_exfat
sudo losetup -d "$LOOP"
rm exfat_test.img
rmdir mnt_exfat

你需要 exfat-fuse 吗?

在现代 Linux 发行版上,通常不是。

自 5.4 版本起,Linux 内核已包含原生 exFAT 驱动程序,大多数当前的发行版默认使用它。在大多数情况下,安装 exfatprogs 就足够了,因为它提供了例如以下的工具:

  • mkfs.exfat
  • fsck.exfat

较老的 Linux 系统通常依赖于:

  • exfat-fuse
  • fuse3

这些软件包在内核获得原生驱动之前提供了 exFAT 支持。它们在某些发行版上仍然可用,但除非您正在使用较旧的 Linux 系统或有意测试 FUSE 实现,否则通常不需要它们。

常见问题解答 (FAQ)

问:为什么当我只改变字母大小写时,mv 会显示“它自身的子目录”?

A: 因为 exFAT 将 Desktops 和 desktops 视为相同的目录名称。当 mv 检查目标是否存在时,文件系统报告它确实存在。然后 mv 假设你正在尝试将一个目录移动到其自身,并打印相应的错误信息。

问:这会发生在 ext4、Btrfs 还是 XFS 上吗?

A:不,默认情况下不是。这些文件系统区分大小写,所以 Desktops 和 desktops 被视为不同的名称。直接重命名通常可以正常工作,无需额外步骤。

问:这会影响 Windows 和 macOS 吗?

A: 是的。exFAT 在设计上不区分大小写,因此 Windows、macOS 和 Linux 在访问 exFAT 卷时都使用相同的规则比较文件名。

问:我可以让 exFAT 区分大小写吗?

A:不可以。大小写不敏感的文件名查找是 exFAT 文件系统规范的一部分。Linux 无法通过挂载选项或配置设置启用大小写敏感。

问:两步重命名会复制我的文件吗?

A:不。两个命令只是重命名同一文件系统中的目录。它们不会复制内容或重新创建目录。

问:我的重命名仍然失败。我应该检查什么?

A:确保临时名称尚不存在。同时确认您对该目录具有写权限,并且源和目标都在同一个 exFAT 文件系统上。

问:我需要一个 exFAT 格式的 USB 驱动器来尝试这个吗?

A: 不可以。你可以使用 Linux 的环回设备在磁盘映像中创建一个临时的 exFAT 文件系统。本指南中的可选部分展示了如何安全地设置、测试和移除它。

结论

这种行为让许多 Linux 用户感到惊讶,因为大多数 Linux 文件系统是区分大小写的。

但是,exFAT 主要是为与 Windows 和可移动存储的兼容性而设计的。它使用 Unicode 大写表确保每个操作系统在比较文件名时保持一致,同时仍然准确显示用户创建的文件名。

理解这一设计不仅有助于解释为什么 mv Desktops desktops 会失败,还能解释为什么两步重命名每次都能成功。

推荐阅读:

  • 在 Linux 中一次重命名多个文件的不同方法
  • 在 Linux 中重命名文件而无需输入完整名称两次