8

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.

  • 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 4 '12 at 17:18
6
+50

*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

  • 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 6: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 6: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 6:24
  • @DanielBeck If you could add steps for setting up a shell function, that would be great! – iglvzx Apr 12 '12 at 6:32
  • 1
    No Bash on Windows available right now to test, but it works like described here. 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 7:09
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;
}
  • 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 6: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
1

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
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
0

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
}
  • If this is an improvement to another answer -- which it looks like it is, well done! -- you could submit it as an edit to that answer :) – bertieb Apr 27 '18 at 16:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.