Home Page
Posts > Windows “ln” (symbolic linking) support for Cygwin
Search:
Windows “ln” (symbolic linking) support for Cygwin
Cygwin requires lots of tweaks to really be usable
The “ln -s” command in Cygwin creates a fake symbolic link only supported in Cygwin. I whipped up the following script to create a true windows symbolic link that is supported in both Windows and Cygwin (it shows up as a symlink in Cygwin).
TARGET=`echo $1 | perl -pe 's/\\//\\\\/g'`; #Determine the target from the first parameter (where we are linking to). Change forward slashes to back slashes
LINK=`echo $2 | perl -pe 's/\\//\\\\/g'` #Determine the link name from the second parameter (where the symlink is made). Change forward slashes to back slashes
cmd /c mklink $3 $4 $5 $6 "$LINK" "$TARGET" #Perform the windows mklink command with optional extra parameters
Note that for the link name, you have to include the full filename, not just specify a directory.
See here for information on mklink and its switches. Specifically:
  • /d : directory symlink (more hard)
  • /j : directory junction (more soft)
This handles the problem a little more directly than my other post on the topic ("Symlinks in a Windows programming environment").

[Edit on 2016-01-12 @ 12:34am]
And once again, I have a new version of the code. This version has the following advantages:
  • No longer limited to just 4 extra parameters (dynamic instead of static)
  • Can now just specify your directory as the link location, and the filename will be automatically filled in
  • Handles spaces better
Do note, if you want to link directly to a hard drive letter, you must use "c:/" instead of "/cygdrive/c/"

#Get the target and link
TARGET="$1"
shift
LINK="$1"
shift

#If the link is already a directory, append the filename to the end of it
if [ -d "$LINK" ]; then
    #Get the file/directory name without the rest of the path
    ELEMENT_NAME=`echo "$TARGET" | perl -pe 's/^.*?\/([^\/]+)\/?$/$1/'`

    #Append the file name to the target, making sure there is only 1 separating "/"
    LINK=`echo "$LINK" | perl -pe 's/^(.*?)\/?$/$1/'`
    LINK="$LINK"/"$ELEMENT_NAME"
fi

#Replace forward slashes with back slashes
TARGET=`echo $TARGET | perl -pe 's/\\//\\\\/g'`
LINK=`echo $LINK | perl -pe 's/\\//\\\\/g'`

#Perform the windows mklink command with optional extra parameters
cmd /c mklink "$@" "$LINK" "$TARGET"

Comments
To add comments, please go to the forum page for this post (guest comments are allowed for the Projects, Posts, and Updates Forums).
Comments are owned by the user who posted them. We accept no responsibility for the contents of these comments.

Re: Windows “ln” (symbolic linking) support for Cygwin on 11/09/15 12:33am by Dakusan
Note: This script need to be rewritten using cygpath
[Edit on 2015-01-12 @ 1:01am]Nevermind on this. Using cygpath forces absolute paths, which is not always desirable. Hmm... maybe I should add a switch that would do that behavior.
Re: Windows “ln” (symbolic linking) support for Cygwin on 04/26/16 6:45am by Dakusan
Just found out that adding "winsymlinks:nativestrict" to your CYGWIN variable in bash makes all internal symlinks use actual windows NTFS symlinks. This is a MUCH better solution, as it will then support all commands that work with symlinks, including rsync.