Run .sh file on double click on Windows with Cygwin

27,977

Solution 1

You have to add a %1 parameter to get the association to work, e.g., like this (quotes are needed to work with paths having embedded blanks):

C:\cygwin64\bin\sh.exe -li  "%1"

The question was asked before in several places; these may be helpful:

The window will close when the script completes, though - unless you make some provision for that in the script, e.g., by following that with a read command (since the association is only passing the script as an argument). Here are a few discussions on that aspect:

Solution 2

I was unhappy with the other answers found here and elsewhere on the Internet, so I've spent a considerable amount of time working out how to do this properly. Here's what I've come up with.

  1. Create a key named .sh and set it's (Default) value to Shell Script under HKEY_CLASSES_ROOT.
    • Create a key named Shell Script under HKEY_CLASSES_ROOT, and set the (Default) value to Shell Script.
  2. Create a key named shell under HKEY_CLASSES_ROOT\Shell Script.
  3. Create a key named open under HKEY_CLASSES_ROOT\Shell Script\shell and set the (Default) value to Run with Cygwin.
  4. Create a key named command under HKEY_CLASSES_ROOT\Shell Script\shell\open and set the (Default) value to "C:\cygwin64\bin\mintty.exe" -i /Cygwin-Terminal.ico C:\cygwin64\bin\bash.exe -l -c "cd $(dirname \"$(cygpath -u \"%1\")\") ; $(cygpath -u \"%1\") ; exec bash" (change C:\cygwin64\ to C:\cygwin\ if you're using the 32bit version).

Now you can just double click on your .sh file and it will run as you expect it to.

Bonus:

  1. Create a key named DefaultIcon under HKEY_CLASSES_ROOT\Shell Script and set the (Default) value to %SystemRoot%\System32\imageres.dll,-68. This will apply the standard Batch file icon to your shell scripts.

I've also created a registry patch file (Save as Run With Cygwin.reg):

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.sh]
@="Shell Script"

[HKEY_CLASSES_ROOT\Shell Script]
@="Shell Script"

[HKEY_CLASSES_ROOT\Shell Script\DefaultIcon]
@="%SystemRoot%\\System32\\imageres.dll,-68"

[HKEY_CLASSES_ROOT\Shell Script\shell]

[HKEY_CLASSES_ROOT\Shell Script\shell\open]
@="Run with Cygwin"

[HKEY_CLASSES_ROOT\Shell Script\shell\open\command]
@="\"C:\\cygwin64\\bin\\mintty.exe\" -i /Cygwin-Terminal.ico C:\\cygwin64\\bin\\bash.exe -l -c \"cd $(dirname \\\"$(cygpath -u \\\"%1\\\")\\\") ; $(cygpath -u \\\"%1\\\") ; exec bash\""

Solution 3

Put the following in a batch file, and select it for "Opens with" for ".sh" files:

@echo off
C:\cygwin\bin\bash.exe -lc "cd ""%cd%""; ""$(cygpath -u "%1")"""

The 'cd ""%cd%"";' part ensures that the shell script will always start in the same directory from which it was called, even if your Bash profile tries to start in your home directory. The multiple layers of double quotes are necessary to escape backslashes and allow for spaces in path names.

An alternative to the login (-l) option, for making sure non-builtin commands are available, is to add the bin directory to your path:

@echo off
set path=%path%;C:\cygwin\bin
bash -c """$(cygpath -u "%1")"""

Solution 4

In the end I found this to be the best solution on my Windows 7 machine.

1.Go to "Control Panel" > "Default Programs" > "Set Associations" and associate .sh file ending with c:\cygwin\bash.exe

2.Open regedit and go to HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open\command and change it to "C:\cygwin\bin\bash.exe" -li "%1"

Found here https://stackoverflow.com/a/106325/1612318 (Matthias' comment)

Solution 5

I've compiled a pretty complete solution to this from here and other posts and sources.

Save as a .reg and double click to add to the registry:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.sh]
@="Shell Script"

[HKEY_CLASSES_ROOT\Shell Script]
@="Shell Script"

[HKEY_CLASSES_ROOT\Shell Script\DefaultIcon]
@="%SystemRoot%\\System32\\imageres.dll,-68"

[HKEY_CLASSES_ROOT\Shell Script\shell]

[HKEY_CLASSES_ROOT\Shell Script\shell\open]

[HKEY_CLASSES_ROOT\Shell Script\shell\open\command]
@="\"C:\\cygwin64\\bin\\mintty.exe\" -i /Cygwin-Terminal.ico -t \"%1\" /bin/bash -lc \"cd \\\"$(dirname \\\"$(cygpath -u \\\"%1\\\")\\\")\\\" ; \\\"$(cygpath -u \\\"%1\\\")\\\" %*\""

[HKEY_CLASSES_ROOT\Shell Script\shell\runas]
"HasLUAShield"=""

[HKEY_CLASSES_ROOT\Shell Script\shell\runas\command]
@="\"C:\\cygwin64\\bin\\mintty.exe\" -i /Cygwin-Terminal.ico -t \"%1\" /bin/bash -lc \"cd \\\"$(dirname \\\"$(cygpath -u \\\"%1\\\")\\\")\\\" ; \\\"$(cygpath -u \\\"%1\\\")\\\" %*\""

This uses C:\cygwin64\bin\mintty.exe and /bin/bash, change the path on both keys if needed.

This solution:

  • Works with simple double-click on any executable .sh file.

  • Runs from the directory the .sh file is in.

  • Allows for running of any command normally in PATH within the .sh file.

  • Doesn't have a problem with .sh files in paths with spaces.

  • Allows for right click -> run as administrator.

  • Closes the window when done.

The only limitations are parameters are passed incorrectly when there's spaces, and dragging and dropping a file to pass its path as a parameter doesn't work.

Share:
27,977

Related videos on Youtube

Rotareti
Author by

Rotareti

Updated on September 18, 2022

Comments

  • Rotareti
    Rotareti almost 2 years

    I created a .sh script file on my Windows machine. I'd like to run it on double click. If I open up the Cygwin Terminal and start it manually with the “sh” command it runs without problems.

    When I associate .sh file endings with c:\cygwin\bin\sh.exe and double click script.sh, a terminal pops up for a millisecond and disappears without effect. I think the problem is that sh.exe needs to be started like this:

    C:\cygwin64\bin\sh.exe --login –i
    

    But how do I tell Windows to run .sh files like that?

  • Totte Karlsson
    Totte Karlsson over 6 years
    Where exactly do you setup this association? I'm on windows 10 and seem only be able to associate a program with a file extension, but not adding/editing parameters to be used.
  • Thomas Dickey
    Thomas Dickey over 6 years
    Some asked that here. This is similar, but older.