Windows为何无法识别WSL符号链接
您是否知道通过Windows Subsystem for Linux (WSL)创建的符号链接无法被Windows系统识别?
最近几个月我在日常工作中使用WSL时遇到了这个令人沮丧的问题。毫无疑问其他人也注意到了这个问题,因此我决定记录下来,为寻找答案的人提供参考。
问题示例
我使用Ubuntu作为WSL2的Linux客户端,创建一个文件并在同一目录下创建符号链接(通过ln -s命令):
|
|
在WSL中,我可以轻松读取原始文件(test_symlink.txt)和符号链接(targetfile.txt)。但当我尝试从Windows文件资源管理器打开符号链接时,会出现错误:
![Windows文件资源管理器错误]
从命令行访问targetfile.txt时也会出现同样的错误:
![命令行错误]
查看目录时,我可以看到目标文件,但其大小为0 KB:
![目录中大小为0 KB的符号链接]
运行dir命令时,可以看到Windows将targetfile.txt识别为NTFS交接点,但无法找到链接指向的位置,就像处理原生Windows符号链接时那样:
![Windows无法找到链接指向位置]
技术原因分析
当我在Twitter上询问这种行为时,Bill Demirkapi给出了答案——WSL创建的链接是"LX符号链接",Windows无法识别。这是因为Linux和Windows上的符号链接实现方式不同:
- 在Windows上,符号链接是一个由内核实现和解释的对象
- 在Linux上,符号链接只是一个带有特殊标志的文件,其内容是目标路径(该路径甚至不需要有效!)
使用FileTest工具,我们可以轻松验证这是一个Linux符号链接,而不是Windows链接。仔细查看甚至可以在文件的DataBuffer中看到目标文件的路径:
![FileTest验证为Linux符号链接]
FileTest还可以提供更具体的文件打开失败错误信息:
![FileTest的文件打开失败错误信息]
事实证明,尝试使用NtCreateFile打开此文件会失败,并返回STATUS_IO_REPARSE_TAG_NOT_HANDLED错误,这意味着Windows将此文件识别为重解析点,但无法识别LX符号链接标签,因此无法跟随它。
反向兼容性测试
有趣的是,在Windows上创建的符号链接在WSL中正常工作。我可以在同一目录中创建一个新文件,并使用Windows命令行(cmd.exe)为其创建符号链接:
|
|
现在Windows将其视为可以识别和跟随的常规符号链接:
![Windows可以跟随Windows创建的符号链接]
而Windows符号链接在WSL中访问时也同样有效:
![Windows符号链接也可以在WSL中访问]
如果我们使用Windows命令行创建文件交接点并尝试用WSL打开,也会得到相同的结果:
|
|
这是从Windows角度看到的目录:
![从Windows角度看到的目录]
这是从WSL角度看到的目录:
![从WSL角度看到的目录]
重要发现
由WSL创建的硬链接在Windows上正常工作,因此此问题仅适用于符号链接。
总结
Windows只能处理使用其标准标签创建的Windows符号链接,无法处理"LX符号链接"类型的WSL符号链接。然而,WSL可以无问题地处理两种类型的符号链接。
如果您同时使用Windows和WSL访问相同的文件,值得注意符号链接的创建方式,以避免遇到我遇到的相同问题。
最后需要指出的是,当Bill Demirkapi测试此行为时,他注意到Windows可以跟随使用相对路径创建的WSL符号链接,但不能跟随使用绝对路径创建的符号链接。在我测试的所有系统上,Windows都无法跟随任何由WSL创建的符号链接。因此,这里仍然存在一些需要进一步调查的谜团。