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.
I have wsl2
activated in my Windows10. I have an Ubuntu-20.04
:
Broken symlinks forbid me to seamlessly "execute in wsl2" while "edit from an IDE in Windows".
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. The application symlinks the library:
/files/repos/my-nice-app
/files/repos/my-nice-lib
my-nice-app/libs/my-nice-lib
is a symlink to ../../my-nice-lib
\\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
.
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.
Whenever I create a symlink from the linux in the NTFS filesystem it is properly decoded in 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.
Imagine this scenario:
I have this dir: /mnt/c/tmp
which corresponds to C:\tmp
.
I put some contents into a file original.txt
. I use the linux bash for that.
From the linux, I do a relative symlink linux.txt
pointing to original.txt
.
I then do it from windows. From a CMD with the mklink
command:
I can even do the symlink in the windows-side with the New-Item
command from an elevated powershell
Up to here I should have one file original.txt
and three links linux.txt
, cmd.txt
and powershell.txt
Success: I do see all them listed in each of the 3 shells: linux, cmd and 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).
Both Linux and CMD also report the "demapping" (4 in the image). 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.
Powershell for some reason which I don't care for this question, promoted the relative symlink to an absolute one. 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:\...
.
Now time to see if I can cat
(type
in windows) the contents of all of them...
No explanation here needed. All 9 combinations (3 creation methods x 3 consumption methods) including the relative and absolute links, all work perfectly.
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
.
Let's start...
I start by the linux. Navigating to /tmp
and creating some dummy content on the WSL2
filesystem. 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:
I'll change my strategy and I'll do a net mount to have a drive letter, see if CMD likes it more. I'll use W:
for the WSL2
filesystem. In the image: 1 = I create it, 2 = I check it is created, 3 = I navigate into tmp
on the WSL2.
But now... oh surprise!!! When I try to do a symlink from the CMD... it denies the access:
Let's try with an elevated 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":
So there's only ONE way to create the symlinks in the WSL2: From inside the linux. Let's see how can we list it and access it.
Starting off, linux can see linux links (of course):
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:
Finally when moving into Powershell the behaviour is similar: It it sees "it is there" but the contents can't be accessed:
How can I have a properly working symlink on WSL2
working well both in the linux side and the windows side?
If it's a bug, what module is it? The kernel? The WSL itself? The P9 protocol? 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.
Overview. Symlinks, or symbolic links, are “virtual” files or folders which reference a physical file or folder located elsewhere, and are an important feature built in to many operating systems, including Linux and Windows. The Windows' NTFS file system has supported symlinks since Windows Vista.
One of the benefits of WSL is being able to access your files via both Windows and Linux apps or tools. Using your mounted drives, you can edit code in, for example, C:\dev\myproj\ using Visual Studio / or VS Code, and build/test that code in Linux by accessing the same files via /mnt/c/dev/myproj .
Access Linux Files from Windows You can access WSL2 Linux files from the network path \\wsl$\ . Enter it in the File Explorer address bar or any file open dialog. Here, <yourname> is the username you defined during installation. It's best to set this as the starting folder for the distro in Windows Terminal.
Install WSLInstall Windows Subsystem for Linux with the command, wsl --install. Use a Bash terminal on your Windows machine run by your preferred Linux distribution - Ubuntu, Debian, SUSE, Kali, Fedora, Pengwin, Alpine, and more are available.
Some expectations for Linux symlink in WSL: can be accessed by Windows' built-in applications (like Notepad), or third-party applications. [bonus] when shown in Windows Explorer, its icon will be decorated with a link icon at bottom-left conor, just like what Windows symlink was decorated.
When a disk has been mounted via WSL2 (Linux file system), it is no longer available to mount via an ext4 driver on the Windows file system. By default, WSL 2 attempts to mount the entire disk. To mount a specific partition, run: This only works if the disk is either MBR (Master Boot Record) or GPT (GUID Partition Table).
A 9p protocol file server provides the service on the Linux side to allow Windows to access the Linux file system. If you cannot access WSL using \\wsl$ on Windows, it could be because 9P did not start correctly. To check this, you can check the start up logs using: dmesg |grep 9p, and this will show you any errors.
Launch your WSL2 Linux distribution. Optionally, secondary click on the top of the window, select Properties, check "Use Ctrl+Shift+C/V as Copy/Paste," and select OK. Run git clone [email protected]:<owner>/<repository> to clone this repository to your Linux file system.
It look like a file permission issue:
When you write in /mnt/c/tmp, you write in the Windows filesystem.
While doing the same in /tmp, you write in the Linux filesystem.
The Linux files are accessed through a Plan9 Server (9P2000L protocol) running on the Windows host with the help of a Unix socket.
The Linux filesystem is accessible through \\wsl$\distribution-name
.
I can suggest the video which explain the access of Linux files in Windows.
Explanation of the access of Linux filesystem with Windows 10
9P2000L protocol
It seems the symlink issue is an open issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With