Cygdir - Cygwin Shell Here

Recently, I helped a friend install Cygwin. One of the issues he had with it is that it's kind of a pain to open a cygwin shell, and then cd to /cygdrive/c/whatever/whatever/whatever... to get to the place you're actually working.

So, I fixed it.

Well, I fixed it as long as you're not on Windows 95, 98, or ME. This uses features of cmd.exe that the older Windows lacks. Please, for your sanity, upgrade.

Installing it.

  1. Grab the file and save it someplace on your computer.
  2. Rename it to cygdir.bat.
  3. Edit the batch file and change the _cygdir_ variable to point to where your cygwin root is. This is a normal Windows path to your Cygwin install. No trailing slashes, please.
  4. Open the Explorer, and select Folder Options from the Tools menu.
  5. Select the File Types tab.
  6. Select an item:
  7. Select the entry labelled "Folder"
  8. Edit it:
  9. Select New
  10. Enter a name in the "Action" edit control. This will be the entry on the right-click menu, so call it "Cygwin Shell Here" or something you like.
  11. Put the full path to the cygdir.bat in the "app" edit control.
  12. Save and exit Folder Options.

You should now have a right-click-here menu.

How It Works

This is Windows batch file that performs the needed magic. It does a little magic.

What it does:

setlocal
Sets any variable changes to be local only, rather than inherited by any subshells. Probably not needed here, but good habit so as not to have batch files scribbling on each other's variables.
set _cygdir_=c:\cygwin
Set up a variable for where Cygwin is installed. Used to make it easier to move to other places. Some of my machines have it on C: and some on D:
for /f "tokens=*" %%c in ('%_cygdir_%\bin\cygpath %1') do @set _cygpath_=%%c
Twistiness one and two, if you don't know these tricks already.
First, Windows NT 4 and later have a great trick in the "for" command that will run a command line, take the results, and parse it as tokens. Very useful.
Second, Cygwin has a command line tool to convert from Windows paths to Cygwin paths, and back again.
This uses that batch trick to run the cygwin tool to convert the first parameter to a cygwin path, instead of a Windows one. It sets that to a variable called _cygpath_, so we can use it later.
c:\cygwin\bin\bash.exe --login -i -c "cd '%_cygpath_%' && exec /bin/bash"
Twistiness three and four: scary Bash tricks. Also maybe another little almost-twistiness from Windows and Bash!
The first trick here is the '--login' parameter, which gets Bash to parse all the .login and .profile and stuff just like you're used to when you log in to a Unix machine, start an SSH session, or open a Cygwin window.
The next one is how we get Bask to start in the directory we want. We launch the login bash with a command line which changes to the directory we want, and then execs bash. Normally, a parent can't change a child's directory, which is what we want, so we have to be creative.
In this case, bash runs, does the login stuff, and then changes directory. Before it exits, it replaces itself with another instance of bash... which starts in the working direcoty the other set, and get all the setup done by the login scripts, etc.
The half-twistiness is the quoting around the command lines to launch Bash. The quoting has to be acceptable to include things with spaces in it properly for both Windows and Bash. Luckily, they get along pretty well, and double quotes can contain single quotes, which Bash lets us use to make a single argument out of the directory we're going to.

Enjoy!