[英]WSL2 - Linux relative symlinks broken when accessed from windows only for the \\wsl$\ mount-point
I am really struggling with relative symlinks on wsl2 when they are created in the linux-native filesystem and I want to access the files via the share point \\\\wsl$\\distro-name\\whatever
- They are simply broken.在 linux 原生文件系统中创建wsl2上的相对符号链接时,我真的很挣扎,我想通过共享点
\\\\wsl$\\distro-name\\whatever
访问这些文件- 它们只是坏了。
I have wsl2
activated in my Windows10.我在 Windows10 中激活了
wsl2
。 I have an Ubuntu-20.04
:我有一个
Ubuntu-20.04
:
Broken symlinks forbid me to seamlessly "execute in wsl2" while "edit from an IDE in Windows".损坏的符号链接禁止我在“从 Windows 中的 IDE 编辑”时无缝地“在 wsl2 中执行”。
Real use case (but not limited to): Developing two intelaced projects: A repo with an application and another repo that lives aside with a library.实际用例(但不限于):开发两个集成项目:一个带有应用程序的 repo 和另一个与库一起存在的 repo。 The application symlinks the library:
该应用程序符号链接库:
/files/repos/my-nice-app
/files/repos/my-nice-app
主程序/files/repos/my-nice-lib
/files/repos/my-nice-lib
my-nice-app/libs/my-nice-lib
is a symlink to ../../my-nice-lib
my-nice-app/libs/my-nice-lib
是../../my-nice-lib
的符号链接\\\\wsl$\\Ubuntu-20.04\\files\\repos\\my-nice-app
\\\\wsl$\\Ubuntu-20.04\\files\\repos\\my-nice-app
With this setup, the location \\\\wsl$\\Ubuntu-20.04\\files\\repos\\my-nice-app\\libs\\my-nice-lib
is expected to map to \\\\wsl$\\Ubuntu-20.04\\files\\repos\\my-nice-lib
.通过此设置,位置
\\\\wsl$\\Ubuntu-20.04\\files\\repos\\my-nice-app\\libs\\my-nice-lib
预计将映射到\\\\wsl$\\Ubuntu-20.04\\files\\repos\\my-nice-lib
。
But it does not work.但它不起作用。 All the code-completion in the IDE is messed up, because the symlink does not de-map well and the IDE can't read the classes and definitions of the library.
IDE 中的所有代码完成都搞砸了,因为符号链接没有很好地解映射并且 IDE 无法读取库的类和定义。
Whenever I create a symlink from the linux in the NTFS filesystem it is properly decoded in windows .每当我在 NTFS 文件系统中从 linux 创建符号链接时,它都会在 windows 中正确解码。
Same the oposite side: If I create the link from windows (both with CMD and mklink
or Powershell with New-Item
) they are properly decoded in linux .反面相同:如果我从 windows (使用 CMD 和
mklink
或 Powershell 使用New-Item
创建链接),它们会在 linux中正确解码。
Imagine this scenario:想象一下这个场景:
I have this dir: /mnt/c/tmp
which corresponds to C:\\tmp
.我有这个目录:
/mnt/c/tmp
对应于C:\\tmp
。
I put some contents into a file original.txt
.我将一些内容放入文件
original.txt
。 I use the linux bash for that.我为此使用了 linux bash。
From the linux, I do a relative symlink linux.txt
pointing to original.txt
.在 linux 中,我做了一个指向
original.txt
的相对符号链接linux.txt
。
I then do it from windows.然后我从窗户做。 From a CMD with the
mklink
command:从带有
mklink
命令的 CMD:
I can even do the symlink in the windows-side with the New-Item
command from an elevated powershell我什至可以使用提升的 powershell 中的
New-Item
命令在 windows 端执行符号链接
Up to here I should have one file original.txt
and three links linux.txt
, cmd.txt
and powershell.txt
到这里我应该有一个文件
original.txt
和三个链接linux.txt
, cmd.txt
和powershell.txt
Success: I do see all them listed in each of the 3 shells: linux, cmd and powershell:成功:我确实在 3 个 shell 中看到了所有这些:linux、cmd 和 powershell:
Here in Linux (1 in the image) we see they are symlinks, as well as from the CMD (2 in the image) and in the powershell (3 in the image).在 Linux(图像中的 1)中,我们看到它们是符号链接,以及来自 CMD(图像中的 2)和 powershell(图像中的 3)中的符号链接。
Both Linux and CMD also report the "demapping" (4 in the image). Linux 和 CMD 也报告了“解映射”(图像中的 4)。 As
cmd.txt
and linux.txt
are both relative symlinks there's no magic to do behind, just understand that they are links and done.由于
cmd.txt
和linux.txt
都是相对符号链接,所以后面没有什么神奇的事情,只要明白它们是链接就可以了。
Powershell for some reason which I don't care for this question, promoted the relative symlink to an absolute one.由于某种我不关心这个问题的原因,Powershell 将相对符号链接提升为绝对符号链接。 This shows up a very interesting effect:
这显示了一个非常有趣的效果:
Somebody behind the scenes must be doing some kind of translation work, which is being done well in this case (5 in the image): While from linux powershell.txt
it is pointing to a path starting with /mnt/c/...
the windows interpreter is seeing it as pointing to C:\\...
.幕后的某个人一定在做某种翻译工作,在这种情况下做得很好(图像中的 5):虽然从 linux
powershell.txt
它指向以/mnt/c/...
开头的路径/mnt/c/...
Windows 解释器将其视为指向C:\\...
。
Now time to see if I can cat
( type
in windows) the contents of all of them...现在的时间,看看我是否能
cat
( type
Windows中)所有这些内容...
No explanation here needed.这里不需要解释。 All 9 combinations (3 creation methods x 3 consumption methods) including the relative and absolute links, all work perfectly.
包括相对链接和绝对链接在内的所有 9 种组合(3 种创建方法 x 3 种消耗方法)都可以完美运行。
Now time for the rule-breakers...现在是打破规则的时候了......
I'll do the very exact same process but instead of doing it on /mnt/c/tmp
I'll do it on /tmp
and in windows, instead of accessing it from C:\\tmp
I'll access it from \\\\wsl$\\Ubuntu-20.04\\tmp
.我将执行完全相同的过程,但不是在
/mnt/c/tmp
执行,而是在/tmp
和 Windows 中执行,而不是从C:\\tmp
访问它,而是从\\\\wsl$\\Ubuntu-20.04\\tmp
访问它\\\\wsl$\\Ubuntu-20.04\\tmp
。
Let's start...开始吧...
I start by the linux.我从linux开始。 Navigating to
/tmp
and creating some dummy content on the WSL2
filesystem.导航到
/tmp
并在WSL2
文件系统上创建一些虚拟内容。 I continue by doing the symlink.我继续做符号链接。
When I try to go there with the CMD I really can't because it complains of being an UNC path:当我尝试使用 CMD 去那里时,我真的不能,因为它抱怨是 UNC 路径:
I'll change my strategy and I'll do a net mount to have a drive letter, see if CMD likes it more.我会改变我的策略,我会做一个网络挂载以获得一个驱动器号,看看CMD是否更喜欢它。 I'll use
W:
for the WSL2
filesystem.我将使用
W:
作为WSL2
文件系统。 In the image: 1 = I create it, 2 = I check it is created, 3 = I navigate into tmp
on the WSL2.在图像中:1 = 我创建它,2 = 我检查它已创建,3 = 我导航到 WSL2 上的
tmp
。
But now... oh surprise!!!但是现在……哦,惊喜!!! When I try to do a symlink from the CMD... it denies the access:
当我尝试从 CMD 执行符号链接时...它拒绝访问:
Let's try with an elevated PowerShell...让我们尝试使用提升的 PowerShell ...
In this image I can see I can properly navigate to the UNC path (1 in the image) but when trying to create the link... boom... 2 in the image: "Symbolic links are not compatible with the specified path":在此图像中,我可以看到我可以正确导航到 UNC 路径(图像中的 1),但是在尝试创建链接时...繁荣...图像中的 2:“符号链接与指定路径不兼容” :
So there's only ONE way to create the symlinks in the WSL2: From inside the linux.所以只有一种方法可以在 WSL2 中创建符号链接:从 linux 内部。 Let's see how can we list it and access it.
让我们看看如何列出并访问它。
Starting off, linux can see linux links (of course):开始,linux 可以看到 linux 链接(当然):
But when moving to CMD, the listing shows "JUNCTION" instead of "SYMLINK" as it showed it on the NTFS and additionally when trying to access it, it breaks:但是当移动到 CMD 时,列表显示“JUNCTION”而不是“SYMLINK”,因为它在 NTFS 上显示它,另外在尝试访问它时,它会中断:
Finally when moving into Powershell the behaviour is similar: It it sees "it is there" but the contents can't be accessed:最后,当进入 Powershell 时,行为类似:它看到“它就在那里”,但无法访问内容:
How can I have a properly working symlink on WSL2
working well both in the linux side and the windows side?如何在
WSL2
上有一个正常工作的符号链接在 linux 端和 windows 端都能正常工作?
If it's a bug, what module is it?如果它是一个错误,它是什么模块? The kernel?
内核? The WSL itself?
WSL 本身? The P9 protocol?
P9协议? I'd be more than happy to contribute but I'd even don't know what project should I contribute to.
我很乐意做出贡献,但我什至不知道我应该为哪个项目做出贡献。
I have deepely read in full all of these:我已经深入阅读了所有这些内容:
and many more, but still no luck.还有更多,但仍然没有运气。
It look like a file permission issue:它看起来像一个文件权限问题:
When you write in /mnt/c/tmp, you write in the Windows filesystem.当您写入 /mnt/c/tmp 时,您写入的是 Windows 文件系统。
While doing the same in /tmp, you write in the Linux filesystem.在 /tmp 中执行相同操作时,您在 Linux 文件系统中写入。
The Linux files are accessed through a Plan9 Server (9P2000L protocol) running on the Windows host with the help of a Unix socket. Linux 文件是通过在 Windows 主机上运行的 Plan9 服务器(9P2000L 协议)在 Unix 套接字的帮助下访问的。
The Linux filesystem is accessible through \\\\wsl$\\distribution-name
. Linux 文件系统可通过
\\\\wsl$\\distribution-name
。
I can suggest the video which explain the access of Linux files in Windows.我可以推荐一个解释在 Windows 中访问 Linux 文件的视频。
Explanation of the access of Linux filesystem with Windows 10 使用Windows 10访问Linux文件系统的说明
9P2000L protocol 9P2000L协议
It seems the symlink issue is an open issue .符号链接问题似乎是一个悬而未决的问题。
I'm not aware of a way to make use of relative symbolic links in order to do what you want.我不知道有什么方法可以利用相对符号链接来做你想做的事。 I suspect there is no sane and reasonable solution to your question as stated besides perhaps fixing the bug linked in the other answer.
我怀疑除了可能修复其他答案中链接的错误之外,您的问题没有理智合理的解决方案。 I recommend taking a different approach altogether that addresses your underlying need of executing in WSL2 and editing in Windows.
我建议完全采用不同的方法来满足您在 WSL2 中执行和在 Windows 中编辑的潜在需求。 Our team has the same underlying need, and I have invested considerable (but certainly not exhaustive) effort experimenting with a variety of strategies.
我们的团队有相同的潜在需求,我投入了大量(但肯定不是详尽无遗)的努力来试验各种策略。 My personal recommendation is to use Git to clone your clone , but if anyone has any better ideas, I am all ears!
我个人的建议是使用 Git 来克隆您的 clone ,但如果有人有更好的想法,我会全力以赴!
git clone git@github.com:<owner>/<repository>
to clone this repository to your Linux file system.git clone git@github.com:<owner>/<repository>
将此存储库克隆到您的 Linux 文件系统。git clone ~/source/repos/<repository> /mnt/<drive>/Users/<username>/.../<repository> --branch main
.git clone ~/source/repos/<repository> /mnt/<drive>/Users/<username>/.../<repository> --branch main
。 This allows you to push to and pull from the clone in the Linux file system. Another option would be to run rsync --archive --delete-after <path to Windows copy> <path to Linux copy>
from your WSL2 Linux distribution.另一种选择是从 WSL2 Linux 发行
rsync --archive --delete-after <path to Windows copy> <path to Linux copy>
运行rsync --archive --delete-after <path to Windows copy> <path to Linux copy>
。 This way you can efficiently copy any changes made to your project in the Windows file system to the Linux file system before execution.通过这种方式,您可以在执行之前有效地将 Windows 文件系统中对项目所做的任何更改复制到 Linux 文件系统。 You could even configure a cron job to automatically run rsync in the background periodically if the Linux side is read-only.
如果 Linux 端是只读的,您甚至可以配置一个 cron 作业来定期在后台自动运行 rsync。
I don't recommend copying files between file systems using Windows-side tools like PowerShell (or even Git Bash), because the Linux file system has more granular permissions that Windows tools have a tendency to mangle.我不建议使用 Windows 端工具(如 PowerShell(甚至 Git Bash))在文件系统之间复制文件,因为 Linux 文件系统具有更细粒度的权限,而 Windows 工具倾向于破坏。 The one exception is Git, because Git itself handles these sorts of cross-platform compatibility issues regardless of how it is run.
一个例外是 Git,因为 Git 本身会处理这些类型的跨平台兼容性问题,而不管它如何运行。 You should, however, configure your .gitattributes appropriately to manage differences in line endings automatically.
但是,您应该适当地配置.gitattributes以自动管理行尾差异。
On October 5th, 2021, Microsoft released Windows 11 withLinux GUI app support . 2021 年 10 月 5 日,微软发布了支持 Linux GUI 应用程序的Windows 11。 Thus, instead of doing any of this, if it's acceptable, you could simply use an IDE for Linux, such as VSCode .
因此,如果可以接受,您可以简单地使用 Linux 的 IDE,例如VSCode ,而不是执行任何这些操作。 (This doesn't solve my team's problem unfortunately, because we execute on both the Linux and Windows sides.)
(不幸的是,这并没有解决我团队的问题,因为我们在 Linux 和 Windows 端都执行。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.