I spent more time than I care to admit trying to figure out how to make symlinks generated through Windows Ubuntu (also known as WSL, Windows Subsystem for Linux) recognizable in Windows.
I kept using this command: ln -s my-actual-dir my-symlink
. And it would create a file instead of a directory. Also, it would be readable from Windows Ubuntu but not in Windows 10. This was an issue because I was trying to create a symlink to a theme folder inside the WordPress theme directory. And although the file was there, there was no way for me to activate the theme from the WordPress dashboard because it wasn’t really a folder, just a file.
Symlinks created using the mklink
command are recognized in Windows 10 and Windows Ubuntu sooo I decided to just use it instead of trying to figure out why ln -s <target> <link>
was not working. Fortunately, I found this mklink.sh
bash script a very long time ago (thanks to stackoverflow) in 2017.
What I did from within Windows Ubuntu:
- First I created the
mklink
bash script and stored in my$HOME/bin
directory:
cd ~ //(to my home directory)
mkdir bin // The internet said it makes sense to store this file in $HOME/bin directory
cd bin
touch mklink.sh
nano mklink.sh
- Then I used the editor and paste in everything from this gist:
- Then I added this line:
export PATH="$HOME/bin:$PATH"
to my.bashrc
file - Navigate back to your home directory or wherever you’ve stored an alias file and create an alias for the
mklink
script
cd ~
nano .bash_aliases
alias mklink=" . mklink.sh"
- Save the file, close the terminal and reopen it. Remember you can’t modify WSL files in the Windows environment which is why I use the nano command to edit files within the terminal. Don’t you dare try to modify that file from a text editor in Windows!
Big Reveal
Try creating a symlink from WSL now using this command:mklink <link> <target>
. Remember the <target>
is the location where all the files actually exists and < link>
is where you want to create a symlink which will mirror everything from the <target>
.
Here is a screen recording of me creating a symlink using this script, and some screenshots at the bottom!
Screen shots
Helpful tips: What to do when…
The pwd is inside of WSL directories:
\\wsl$\Ubuntu\home\badgirlriri
), and you’re attempting to create a symlink from a target directory on Windows, you can create a symlink using an absolute path:mklink /projects/mklink-test/symlink1 /projects/mklink-test/target
The pwd is inside of your WSL symlink
ln -s /mnt/c/projects/ myProjects
) and which results in a directory listing like: myProjects -> /mnt/c/projects,
then when your pwd is ~/myProjects
, you can use relative paths:mklink mklink-test/symlink2 mklink-test/target
The pwd is inside of a Windows directory
/mnt/c
or /mnt/c/projects
or /mnt/c/Users/Rihanna
), you can create a symlink using an absolute path or a relative path (if you’re in the directory) using one of the following commands.## Absolute Path from pwd /mnt/c
mklink projects/mklink-test/symlink3 projects/mklink-test/target
## Relative Path from pwd /mnt/c/projects
mklink mklink-test/symlink4 mklink-test/target
## Relative Path from pwd /mnt/c/projects to a completely different directory referenced by the absolute path
mklink /newProjects/mklink-test-2/symlink5 mklink-test/target # note that the link path is absolute here
This post was made possible by a lot of google searching, a few links are below:
14 comments on “Using the mklink command in Windows Ubuntu (WSL)”
I was suffering the same issue. Can you edit symlinked files from Win10?
I’d need to look at any updates they’ve made to WSL since, but I think you should be able to if the file that is symlinked lives anywhere in /mnt/c . In the example I shared, those files lived in my Windows file system and the point of using mklink was creating a symlink that is recognizable by both WSL and Windows and can absolutely be accessed from Windows, which is where I have GUI for text editing. Hope that helped.
You can open WSL home folder using `explorer.exe .`. Run that command on bash. Anyway, thanks for this trick. Help me so much getting my dotfiles available on WSL
Hi. Wait, how come you are passing arguments to “`cmd“` like is regular Linux. Don’t you need “`cmd.exe /c“` in the symlink option?
When is the function “`symlink“` called?
I know %windir% is a thing in Windows but what is “`$WINDIR“` here?
The way the script is right now, only the 3rd line gets executed, so it only works for folders.
I actually updated the %windir% part of the script. The only necessary part reflected in the updated gist in the post. The cmd required for using cmd.exe is actually the core part of the script.
I’m afraid this doesn’t work for absolute paths. I attempt to run
`mklink current /home/sturm/winhome/dev/Projects/sky-open-template/releases/8`
and it creates a link called `current` which points to
`/mnt/c/home/sturm/winhome/dev/Projects/sky-open-template/releases/8`
which is invalid. How can this be fixed?
It does work for absolute paths. I updated the post with some hopefully helpful information about how to format the command based on the pwd.
In linux, you can refer to your home directory using the tilde symbol, so in your case it would go something like this `mklink current ~/winhome/dev…
. I omitted the /home/sturm part because I’m assuming that is your home directory and “winhome” is a folder stored at the root of it.
Sorry, I never got a notification that you responded to my comment and WordPress was complaining about my email address not matching the one they have on file for me, so I posted it a second time (albeit worded differently).
Anyway,
winhome
is a symlink that Pengwin (an alternative to Ubuntu that’s made for WSL) creates automatically, so maybe that’s tripping it up?I actually have tried using the tilde version, too:
mklink current ~/winhome/dev/Projects/sky-open-template/releases/8
but that creates the same dead link:
current ⇒ /mnt/c/home/sturm/winhome/dev/Projects/sky-open-template/releases/8 [Dead link]
If there’s no way around this, then I’ll just move my
/dev
folder to the WSL home instead.Is there any way for this script to not automatically prepend
/mnt/c
to everything?I attempt make a link like so:
mklink current /home/sturm/winhome/dev/Projects/sky-open-template/releases/8
However, the resulting entry for
current
when I runls -lah
is:current ⇒ /mnt/c/home/sturm/winhome/dev/Projects/sky-open-template/releases/8 [Dead link]
Btw,
winhome
is a symlink that points to/mnt/c/Users/christopher.mcgee
. I wonder if that is a linux-native symlink and so it’s throwing offmklink
and causing the [Dead link] result?WSL automatically prepends
/mnt/c
, that is not a function of the script. You can probably look into workarounds for thatI definitely think it is a linux symlink issue. Your WSL home lives on what functions like a network share, so the actual path to it would be
//wsl$/Ubuntu/home/sturm...
so Windows doesn’t recognize the path/home/sturm
and of course mklink is a windows command. It will default to the Windows root directory if it can’t find it, which is how I think the bad link is being generated.You’ll have success with using the standard linux command
ln -s ~/winhome current
but you probably won’t be able to access that current directory from any Windows interfaces.You can also look into mounting the “network share” but I’m not sure it is worth the effort. That said, you’ll probably have better luck with the actual absolute path:
mklink current /mnt/c/Users/chris/winhome...
Yeah, that’s what I thought. So I’ve decided to move all of my development files to a directory under my WSL home instead of keeping it under Windows home. That way I won’t have to worry about it anymore.
Thank you so much for your kind help!
Hi, struggling to get this working. I’m kind of new to this, so maybe I’m making a simple mistake.
I’d like to link my projects folder in WSL to somewhere in the windows file system. Preferable I would like the link to reside in my Google Drive, so as to be accessible across multiple devices. The projects folder is at
~/projects
, and my gdrive is at/mnt/c/users/kvnlo/Google Drive
. I triedrunning
mklink "/Users/kvnlo/Google Drive/wsl-projects" ~/projects
from ~ and received the following response:
'\\wsl$\Ubuntu-18.04\home\kloughead'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported. Defaulting to Windows directory.
Junction created for \Users\kvnlo\Google Drive\wsl-projects <<===>> \home\kloughead\projects
However, navigating to gdrive and checking
file wsl-projects
yieldswsl-projects: broken symbolic link to /mnt/c/home/kloughead/projects
In the thread above you mention WSL automatically preprending
/mnt/c
. I don’t understand why that would be. I specified that myprojects
folder was in~
, which in all other contexts I’ve encountered within WSL refers to/home/me
, not/mnt/c/home/me
. Would you be able to elaborate on this, and/or suggest a workaround?I think the issue you’re running into is trying to create a symlink between two different systems. Touched on that in one of the previous comments, you might not be able to successfully do what you’re trying to do.
You’ve probably figured this out already but
mklink
is a Windows function and it can’t figure out what the origin point is for~/projects
since it lives on the WSL network share-like environment, so it falls back on/mnt/c
.If your project folder actually lived in the legacy Windows system and you could create a linux symlink in WSL to the Windows project folder, he mklink might work.
You could also try the standard linux symlink but you won’t actually be able to access any of the files in Windows.
I do wonder if you figured it out, I’m not entirely sure what you’re trying to do though so feel free to elaborate.
The error message you got is supporting what I said: “UNC paths are not supported. Defaulting to Windows directory.”