我很少(但有时)会遇到以下问题:WSL 和 Windows 看到的文件不同。
foo
我在驱动器上有一个名为的目录D
。我将其从 Windows 中删除,然后发生了一些奇怪的事情。该目录变得不可见且无法删除,但我可以在 WSL 中输入它!
home:/mnt/d$ ll
total 0
drwxrwxrwx 1 user user 4096 Oct 31 14:46 ./
drwxrwxrwx 1 user user 4096 Oct 31 14:45 ../
drwxrwxrwx 1 user user 4096 May 2 08:59 bar/
home:/mnt/d$ rm foo
rm: cannot remove 'foo': Is a directory
home:/mnt/d$ rm -rf foo
home:/mnt/d$ rm -rf foo
home:/mnt/d$ cd foo
home:/mnt/d/foo$ ll
total 0
drwxrwxrwx 1 user user 4096 Oct 31 14:46 ./
drwxrwxrwx 1 user user 4096 Oct 31 14:45 ../
我不知道根本原因。
唯一的解决方案是关闭所有 WSL 实例,包括所有后台和 GUI 应用程序。然后打开一个新的 WSL。
有没有更好的解决方案?(我不想重新启动所有 WSL)
我用:
- Windows 10 专业版
- 版本 10.0.18362 内部版本 18362
答案1
我没有办法解决这个问题,但我可以指出问题的根源。
Windows和Linux的二重性,都建立在同一套Windows API之上,使得微软做出了很多妥协。
首先,由于 Linux 和 Windows 之间的文件元数据不同,微软决定将 Linux 元数据作为文件内的分支存储。这意味着不保存分支的操作将破坏 Linux 元数据。例如,所有通过创建新版本来更新文件的 Windows 操作都将丢失文件的 Linux 属性。
黄金法则是,Linux 文件应在 Linux 中操作,Windows 文件应由 Windows 操作。违反这些规则可能会导致奇怪的副作用和不一致。
有关此内容的更多信息,请参阅 Microsoft 博客
不要使用 Windows 应用和工具更改 Linux 文件。
Windows 10 版本 1903 中已经对这种情况进行了改进,如文章中所述 Windows 10 版本 1903 中更新的 WSL 可让你从 Windows 访问 Linux 文件。对于此类操作,我们仍需谨慎,仔细测试当前哪些方法可行,哪些方法不可行。上述文章中的以下引文表明,这是一个持续的过程:
Linux 和 Windows 之间的联姻越来越紧密。微软通过 WSL(适用于 Linux 的 Windows 子系统)拥抱了 Linux,现在正在做用户一直渴求的事情:Windows 10 2019 年 4 月更新使从 Windows 访问 Linux 文件成为可能。
Windows/Linux 的二分法造成了一种非常低效的结构,Linux 需要从文件中读取数据才能访问其元数据。Linux 文件系统则基于 Inode 和驻留在内存中的文件表,没有这些,性能根本无法实现。
微软的解决方案是为 Linux 创建一个名为 VolFs 的虚拟文件系统。挂载的 Windows 磁盘使用 DrvFs,两者非常相似。
引用微软博客 WSL 文件系统支持:
VolFs用于挂载VFS根目录,
%LocalAppData%\lxss\rootfs
作为后备存储。由于 Windows 没有相关的 inode 概念,VolFs 必须在 inode 中保留 Windows 文件对象的句柄。当 VFS 使用查找回调请求新 inode 时,VolFs 使用父 inode 中的句柄和子 inode 的名称执行相对打开并获取新 inode 的句柄。这些句柄在打开时不具有对文件的任何读/写访问权限,只能用于元数据请求。
打开文件时,VolFs 会创建一个指向 inode 的 Linux 文件对象。它还会重新打开 inode 的文件句柄并赋予其所请求的读/写访问权限,并将新句柄存储在文件对象中。然后,此句柄将用于满足读写等文件操作。
实际上,这里并行存在两个文件系统,Windows NTFS 和 WSL VFS,并且无法保证一致性。
任何解决问题的方法都必须来自微软。您应该确保始终使用最新版本的 Windows 10,因为微软仍在努力解决这些问题。