WSL2 - 仅在 \\wsl$\ 挂载点从 Windows 访问时,Linux 相关符号链接损坏 [关闭]

Posted

技术标签:

【中文标题】WSL2 - 仅在 \\\\wsl$\\ 挂载点从 Windows 访问时,Linux 相关符号链接损坏 [关闭]【英文标题】:WSL2 - Linux relative symlinks broken when accessed from windows only for the \\wsl$\ mount-point [closed]WSL2 - 仅在 \\wsl$\ 挂载点从 Windows 访问时,Linux 相关符号链接损坏 [关闭] 【发布时间】:2021-02-05 21:34:23 【问题描述】:

问题

wsl2 上的 相对符号链接 在 linux-native 文件系统中创建时,我真的很苦恼,我想通过共享点访问这些文件\\wsl$\distro-name\whatever - 他们只是坏了。

环境

我在 Windows10 中激活了wsl2。我有一个Ubuntu-20.04

对我的编码工作流程的影响

损坏的符号链接禁止我在“从 Windows 中的 IDE 编辑”时无缝地“在 wsl2 中执行”。

实际用例(但不限于):开发两个相互关联的项目:一个带有应用程序的 repo 和另一个与库一起存在的 repo。应用程序符号链接库:

/files/repos/my-nice-app中的主程序 库也在/files/repos/my-nice-lib my-nice-app/libs/my-nice-lib../../my-nice-lib 的符号链接 windows中的智能IDE,在打开\\wsl$\Ubuntu-20.04\files\repos\my-nice-app的应用程序上运行

通过此设置,位置 \\wsl$\Ubuntu-20.04\files\repos\my-nice-app\libs\my-nice-lib 预计将映射到 \\wsl$\Ubuntu-20.04\files\repos\my-nice-lib

但它不起作用。 IDE 中的所有代码完成都搞砸了,因为符号链接没有很好地解映射,并且 IDE 无法读取库的类和定义。

如何重现工作示例

工作示例。第 1 步 - 准备

每当我在 NTFS 文件系统中从 linux 创建符号链接时,它都会在 Windows 中正确解码

相反的一面:如果我从 Windows 中创建链接(使用 CMD 和 mklink 或使用 New-Item 的 Powershell),它们会在 linux 中正确解码 .

想象一下这个场景:

    我有这个目录:/mnt/c/tmp,对应于C:\tmp

    我将一些内容放入一个文件original.txt。我为此使用了linux bash。

    在 linux 中,我做了一个相对符号链接 linux.txt 指向 original.txt

    然后我从 Windows 执行此操作。从带有 mklink 命令的 CMD 中:

    我什至可以使用提升的 powershell 中的New-Item 命令在 Windows 端进行符号链接

到这里我应该有一个文件original.txt和三个链接linux.txtcmd.txtpowershell.txt

工作示例。第 2 步 - 列出符号链接

成功:我确实看到它们都列在 3 个 shell 中:linux、cmd 和 powershell:

在 Linux 中(图像中的 1),我们看到它们是符号链接,以及来自 CMD(图像中的 2)和 powershell(图像中的 3)的符号链接。

Linux 和 CMD 都报告了“去映射”(图中的 4)。由于cmd.txtlinux.txt 都是相对符号链接,所以后面没有什么神奇的,只要明白它们是链接就可以了。

Powershell 出于某种我不关心这个问题的原因,将相对符号链接提升为绝对符号链接。这显示了一个非常有趣的效果:

幕后的某人一定在做某种翻译工作,在这种情况下做得很好(图片中的 5):虽然从 linux powershell.txt 它指向一个路径从/mnt/c/... 开始,Windows 解释器将其视为指向C:\...

工作示例。第 3 步 - 通过符号链接访问内容

现在是时候看看我是否可以cat(Windows 中为type)所有这些内容...

这里不需要解释。包括相对链接和绝对链接在内的所有 9 种组合(3 种创建方法 x 3 种消费方法)都可以完美运行。

现在是打破规则的时候了……

如何重现失败的示例

我将执行完全相同的过程,但不是在 /mnt/c/tmp 上执行此操作,而是在 /tmp 和 Windows 中执行此操作,而不是从 C:\tmp 访问它'将从\\wsl$\Ubuntu-20.04\tmp 访问它。

开始吧……

失败的例子。第 1 步 - 准备

我从 linux 开始。导航到/tmp 并在WSL2 文件系统上创建一些虚拟内容。我继续做符号链接。

当我尝试使用 CMD 去那里时,我真的不能,因为它抱怨是 UNC 路径:

我会改变我的策略,我会做一个网络挂载来获得一个驱动器号,看看 CMD 是否更喜欢它。我将W: 用于WSL2 文件系统。在图像中:1 = 我创建它,2 = 我检查它是否已创建,3 = 我导航到 WSL2 上的tmp

但是现在……哦,惊喜!!!当我尝试从 CMD 进行符号链接时...它拒绝访问:

让我们尝试使用提升的 PowerShell...

在这张图片中,我可以看到我可以正确导航到 UNC 路径(图片中的 1),但是在尝试创建链接时...繁荣...图片中的 2:“符号链接与指定路径”:

所以只有一种方法可以在 WSL2 中创建符号链接:从 linux 内部。让我们看看如何列出并访问它。

失败的例子。第 2 步 - 上市 + 访问

启动,linux可以看到linux链接(当然):

但是当移动到 CMD 时,列表显示“JUNCTION”而不是“SYMLINK”,因为它在 NTFS 上显示,此外,当尝试访问它时,它会中断:

最后,当移动到 Powershell 时,行为是相似的:它看到“它在那里”,但无法访问内容:

最后的考虑

我什至不要求进行绝对路径转换(正如在 NTFS 工作中所证明的那样)。我对相关链接很满意 我已经用文件做到了这一点。但它也因目录而失败。

好棒的问题

我怎样才能让WSL2 上的符号链接在 linux 端和 Windows 端都能正常工作?

如果是错误,它是什么模块?内核? WSL 本身? P9 协议?我很乐意贡献,但我什至不知道我应该为什么项目贡献。

目前已完成调查

我已经深入阅读了所有这些内容:

https://docs.docker.com/docker-for-windows/wsl/ https://medium.com/@ragin/development-under-windows-under-linux-with-wsl2-intellij-860daf601b61 https://docs.microsoft.com/es-es/windows/wsl/tutorials/wsl-git https://docs.microsoft.com/es-es/windows/win32/fileio/hard-links-and-junctions?redirectedfrom=MSDN https://docs.microsoft.com/es-es/windows/win32/fileio/creating-symbolic-links https://www.docker.com/blog/new-docker-desktop-wsl2-backend/

还有更多,但仍然没有运气。

【问题讨论】:

在我问这个问题之前,@trentis 在官方仓库中打开的问题:github.com/microsoft/WSL/issues/5118。 在这里交叉引用intellij-support.jetbrains.com/hc/en-us/community/posts/… 已移至超级用户 superuser.com/q/1695779/324451 【参考方案1】:

看起来像是文件权限问题: 当您写入 /mnt/c/tmp 时,您写入的是 Windows 文件系统。 在 /tmp 中执行相同操作时,您将写入 Linux 文件系统。 借助 Unix 套接字,可通过在 Windows 主机上运行的 Plan9 服务器(9P2000L 协议)访问 Linux 文件。 Linux 文件系统可通过\\wsl$\distribution-name 访问。 我可以推荐一个解释在 Windows 中访问 Linux 文件的视频。 Explanation of the access of Linux filesystem with Windows 10 9P2000L protocol

似乎符号链接问题是open issue。

【讨论】:

虽然这都是 true,但它似乎只与 OP 的符号链接问题无关。 似乎符号链接问题是一个未解决的问题。 \github.com/microsoft/WSL/issues/4868 @FrançoisB。首先,感谢您的宝贵时间。您能否将指向“未决问题”的指针作为答案本身的一部分,以便能够将其选为“答案”? 虽然这个答案不能解决问题的问题,但我们感谢您的努力!如果有人跟进解决方案,我们很乐意再次奖励。【参考方案2】:

我不知道有一种方法可以利用相对符号链接来做你想做的事。我怀疑除了可能修复另一个答案中链接的错误之外,您的问题没有理智和合理的解决方案。我建议采用完全不同的方法来解决您在 WSL2 中执行和在 Windows 中编辑的基本需求。我们的团队有同样的潜在需求,我投入了大量(但肯定不是详尽的)努力尝试各种策略。我个人的建议是使用 Git 克隆您的克隆,但如果有人有更好的想法,我会全力以赴!

启动您的 WSL2 Linux 发行版。 (可选)第二次单击窗口顶部,选择“属性”,选中“使用 Ctrl+Shift+C/V 作为复制/粘贴”,然后选择“确定”。 运行 git clone git@github.com:<owner>/<repository> 将此存储库克隆到您的 Linux 文件系统。 将您的克隆克隆到 Windows 文件系统:git clone ~/source/repos/<repository> /mnt/<drive>/Users/<username>/.../<repository> --branch main。这允许您在 Linux 文件系统中推送和提取克隆。

另一种选择是从您的 WSL2 Linux 发行版运行 rsync --archive --delete-after <path to Windows copy> <path to Linux copy>。通过这种方式,您可以在执行之前有效地将对 Windows 文件系统中的项目所做的任何更改复制到 Linux 文件系统。如果 Linux 端是只读的,您甚至可以配置 cron 作业以定期在后台自动运行 rsync。

我不建议使用 Windows 端工具(如 PowerShell(甚至 Git Bash))在文件系统之间复制文件,因为 Linux 文件系统具有更精细的权限,而 Windows 工具往往会破坏这些权限。一个例外是 Git,因为无论它如何运行,Git 本身都会处理这些类型的跨平台兼容性问题。但是,您应该适当地配置您的 .gitattributes 以自动管理行尾的差异。

2021 年 10 月 5 日,微软发布了带有Linux GUI app support 的 Windows 11。因此,如果可以接受,您可以简单地使用适用于 Linux 的 IDE,例如 VSCode,而不是执行任何这些操作。 (不幸的是,这并没有解决我团队的问题,因为我们在 Linux 和 Windows 端都执行。)

【讨论】:

以上是关于WSL2 - 仅在 \\wsl$\ 挂载点从 Windows 访问时,Linux 相关符号链接损坏 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何在Win10上安装docker

如何在Win10上安装docker

docker desktop win10挂载问题解决

从 WSL2 恢复到 WSL1

WSL1 升级为 WSL2

WSL2的安装应用