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!

gif showing how to use the mklink command in WSL

Screen shots

Helpful tips: What to do when…


The pwd is inside of WSL directories:
If you’re in your WSL home directory (e.g. the pwd is \\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
**FYI: You need to omit the `/mnt/c` part of the path. I typically have issues when that is prepended.

 

The pwd is inside of your WSL symlink
If you’re like me and have linux symlinks created using this command (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
If you’re in a Windows directory (e.g., the pwd is somewhere in /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:

12 comments on “Using the mklink command in Windows Ubuntu (WSL)

    1. 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.

      1. 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

  1. 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.

    1. 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.

  2. 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?

    1. 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.

      1. 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.

  3. 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 run ls -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 off mklink and causing the [Dead link] result?

    1. WSL automatically prepends /mnt/c, that is not a function of the script. You can probably look into workarounds for that

      I 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...

      1. 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!

Leave a Reply

Your email address will not be published. Required fields are marked *