11

I use msysgit on Windows to use git, but I often want to navigate through a Windows-style *.lnk shortcut. I typically manage my file structure through Windows' explorer, so using a different type of shortcut (such as creating hard or soft link in git) isn't feasible. How would I navigate through this type of shortcut?

For example:

PCUser@PCName ~
$ cd Desktop

PCUser@PCName ~/Desktop
$ ls
Scripts.lnk

PCUser@PCName ~/Desktop
$ cd Scripts.lnk
sh.exe": cd: Scripts.lnk: Not a directory

Is it possible to change this behavior, so that instead of getting an error, it just goes to the location of the directory? Alternatively, is there a command to get the path in a *.lnk file?

EDIT: I've heard that the inverse of this exists for cygwin, allowing you to create a symlink which works with explorer.

Casey Kuball
  • 456
  • 5
  • 18
  • 2
    Not really an answer to your question, but if you use the `mklink` command to create an NTFS soft link I think it'll work like you want it to. – jcrawfordor Apr 04 '12 at 17:18

5 Answers5

8

*ahem*

First, compile the following AutoHotkey script:

FileGetShortcut, %1%, shortcut_target
FileAppend, %shortcut_target%, *
ExitApp

Place the .EXE file in a %PATH% directory. I named mine follow.exe.

Now, you can effectively follow a Windows .LNK file in your working directory by using the following syntax:

cd `follow Shortcut.lnk`

where Shortcut.lnk's target is a valid directory.


Demonstration:

shortcut

git bash


Once you've set up your follow.exe, you can add the following shell function to your ~/.bashrc file to simplify the syntax even further. Thanks, Daniel!

function cd
{
    if [[ ".lnk" = "${1:(-4)}" && -f "$1" ]] ;
        then builtin cd "$( follow "$1" )" ;
    else builtin cd "$1" ;
    fi
}

Now, you can follow .LNK files with just cd!

cd Shortcut.lnk

Demonstration:

cd

iglvzx
  • 23,459
  • 13
  • 85
  • 122
  • This is great! I was actually learning about using the tick mark syntax to evaluate commands, but this answer provides the exact step I was missing. Thanks!! I'm just curious about one thing -- does this work for network mapped drives and/or network locations? I don't particularly need it for this, but it would be useful to know. :) – Casey Kuball Apr 12 '12 at 06:12
  • If you can `cd` to the **target** as set in the shortcut file (e.g. see first screenshot), then it should work. This just saves you a couple of steps with the help of AutoHotkey. :) – iglvzx Apr 12 '12 at 06:15
  • 1
    Very cool. Using a cd shell function you could automatically do this when cding to lnk files. – Daniel Beck Apr 12 '12 at 06:24
  • @DanielBeck If you could add steps for setting up a shell function, that would be great! – iglvzx Apr 12 '12 at 06:32
  • 1
    No Bash on Windows available right now to test, but [it works like described here](http://superuser.com/a/283365/22317). This might work for the function definition: `function cd { if [[ ".lnk" = "${1:(-4)}" && -f "$1" ]] ; then builtin cd "$( follow "$1" )" ; else builtin cd "$1" ; fi }`. If you cd a *file* named `*.lnk`, use `cd` with `follow`, otherwise use regular `cd`. – Daniel Beck Apr 12 '12 at 07:09
  • @DanielBeck It works! We've made a breakthrough in Windows+Bash. :) – iglvzx Apr 12 '12 at 07:31
  • @Darthfett See the updated answer. – iglvzx Apr 12 '12 at 07:33
  • Nice demonstration, seems to work quite well. Nothing primitive about this solution anymore :-) – Daniel Beck Apr 12 '12 at 07:56
  • @iglvzx this is excellent! I'm considering looking into auto-completion for the resulting directory, this works so well. :) – Casey Kuball Apr 12 '12 at 17:50
3

It seems that it's not possible at this moment, and the recommended approach is to use the Junction utility:

About creating symbolic on msys

Update:

Thank you iglvzx for your answer.

However, in my case sometimes the bash autocompletion puts an / after the shortcut, like cd /f/downloads/scripts.lnk/, so I use it as an excuse to play with bash scripting and adjust your script, also checking for not acceptable shortcuts (broken or pointing to files):

cd() {

    shopt -s nocasematch

    if [[ -z "$1" ]];
        then
            echo Error: missing operand;
            return 1;
    fi;

    if [[ "$1" == "/" ]];
        then
            destination=$1;
        else
            destination=${1%/};
    fi;

    extension=${destination##*.}

    if [[ -f "$destination" && $extension == "lnk" ]];
        then

            finaldestination=`follow "$destination"`;

            if [[ -z "$finaldestination" ]];
                then
                    echo Error: invalid destination;
                    return 2;
            fi;

            if [[ -f "$finaldestination" ]];
                then
                    echo Error: destination is a file;
                    return 3;
            fi;

            builtin cd "$finaldestination";

        else
            builtin cd "$destination";
    fi;
}
alexandrul
  • 1,072
  • 1
  • 16
  • 21
  • I wish I could also give bounty to your answer, as it does answer the question, that it doesn't exist. This is great to know, but the issue is that I don't find file management to be simpler in a terminal -- I manage my files and shortcuts with explorer, and thus cannot simply create a symlink. Thanks very much! – Casey Kuball Apr 12 '12 at 06:09
  • Good idea to ignore any trailing `/` characters. MinGW seems to add a trailing space for me. I think `sh.exe` already does the destination checking for you, so that's unnecessary work for the script. What would be interesting to see would be auto-complete for the target directory. – Casey Kuball Apr 12 '12 at 17:48
2

Opening shortcuts from within msys is possible with cmd via the /C flag:

cmd //C "C:\Shortcut.lnk"

If it's a shortcut to a folder, it will be opened. The slash has to be escaped so msys doesn't convert /C to C:\.

Relative paths work as well, and quotes aren't needed for simple paths. If the lnk file is in current folder:

cmd //C Shortcut.lnk
Mihai Rotaru
  • 2,799
  • 5
  • 26
  • 25
1

Wow, awesome approach iglvzx ! I recommend a tiny improvement to your ~/.bashrc script so that a simple cd without any argument still changes to the user's home directory.

function cd
{
    if [[ ".lnk" = "${1:(-4)}" && -f "$1" ]] ;
        then builtin cd "$( follow "$1" )" ;
    elif [[ -z "$1" ]] ;
        then builtin cd ;
    else 
        builtin cd "$1" ;
    fi
}
Bernie Lenz
  • 111
  • 4
  • If this is an improvement to another answer -- which it looks like it is, well done! -- you could [submit it as an edit](https://superuser.com/posts/411363/edit) to that answer :) – bertieb Apr 27 '18 at 16:01
1

If you make a symlink (using mklink /D <link name> <target dir> from cmd with admin privileges) instead of a shortcut, git bash can follow it with cd -P <link name>.

  • It's not a bad idea, but originally I was trying to manage my shortcuts strictly through the GUI, and there's no simple solution in the GUI to create a symlink. Perhaps making that process easier would be an alternative way to get similar behavior in the GUI and command line. – Casey Kuball Aug 28 '18 at 20:24
  • That's a good point. You can't create symlinks in the file explorer, but you can follow them from the file explorer as you would a shortcut. BTW, I think this only works on windows 10. – mikeLundquist Aug 29 '18 at 15:29