How can I associate .sh files with Cygwin?

前端 未结 13 1262
旧时难觅i
旧时难觅i 2021-01-29 21:32

I\'d like to run a long rsync command in Cygwin by double clicking on a .sh file in Windows. It must start in the file\'s containing directory (e.g. /cygdrive/c/scripts/) so th

相关标签:
13条回答
  • 2021-01-29 22:09

    After looking around different places. What I have managed to come up with is, first select C:\cygwin64\bin\mintty.exe from the windows "Open with..." dialog Then edit the registry value of

    [Computer\HKEY_CLASSES_ROOT\Applications\mintty.exe\shell\open\command]
    

    to,

    C:\cygwin64\bin\mintty.exe -t "%1" /bin/bash -l -i -c "v1=\"$(cygpath -u \"%0\" -a)\" && v2=\"$(dirname \"$v1\")\" && cd \"$v2\" ; exec bash  \"%1\" %*"  
    
    0 讨论(0)
  • 2021-01-29 22:10

    Here is my solution. It works well for my *.sh scripts regardless of where they are in the directory hierarchy. Notice that I cd to the cygpath dirname before calling bash on the cygpath. It just works.

    assoc .sh=bashscript
    
    ftype bashscript=C:\cygwin\bin\bash.exe --login -i -c 'cd "$(dirname "$(cygpath -u "%1")")"; bash "$(cygpath -u "%1")"'
    
    0 讨论(0)
  • You should be able to associate .sh files with \CYGWIN\usr\bin\bash.exe. The script will have to change its own working directory, I suggest sticking something like this at the top:

    cd `dirname "$0"`
    
    0 讨论(0)
  • 2021-01-29 22:11

    Ok, I've found something that works. Associating a batch file as Vladimir suggested didn't work, but the bash arguments were key.

    Short and sweet: associate with this command: "C:\cygwin\bin\bash.exe" -li "%1" %*

    Long version if you don't know how:

    1. In Explorer, go to Tools/Folder Options/File Types.
    2. I already had an SH entry for Bash Script. If you don't have one, click New and enter "SH" to create one.
    3. With the SH extension selected, click Advanced.
    4. Choose the "open" action and click edit (or create the action).
    5. This is the command to use: "C:\cygwin\bin\bash.exe" -li "%1" %*. Note that without the -li, it was returing "command not found" on my scripts.

    You may also want to add SH to your PATHEXT environment variable:

    WinKey+Pause / Advanced / Environment Variables / System Variables / PATHEXT

    Thanks for your help, guys!

    0 讨论(0)
  • 2021-01-29 22:12

    Look at the assoc and ftype commands in a dos box. Here's an example for .jpg on my machine

    c:\>assoc .jpg
    .jpg=jpegfile
    
    c:\>ftype jpegfile
    jpegfile="C:\Program Files\Common Files\Microsoft Shared\PhotoEd\PHOTOED.EXE" "%1"
    
    assoc .sh=bashscript
    
    ftype bashscript="c:\cygwin\bin\bash.exe" "%1"
    

    Make sure you change the path to bash in the ftype command to match where you have cygwin installed

    0 讨论(0)
  • 2021-01-29 22:18

    I've been working with Dragos' solution for some time now and I regard it as the best one because it eleminates the need to use "cygpath -u" inside your shell scripts.

    I then wanted to have additional features like drag&drop support for .sh and .bash files. After some digging around I wrote a .bat that associates .sh and .bash files as "bashscript" and activates the Windows Explorer drag&drop handler for them. I had to edit Dragos' command to make it handle 1 argument (the path to the item dropped on a shell script).

    The .bat file roughly goes as follows:

    echo Registering .sh and .bash files as "bashscript"...
    assoc .sh=bashscript
    assoc .bash=bashscript
    echo.
    echo Setting the run command for the file type "bashscript"...
    ftype bashscript=C:\cygwin\bin\bash.exe --login -i -c 'cd "$(dirname "$(cygpath -u "%%1")")"; bash "$(cygpath -u "%%1")" "$(/argshandler.sh "%%2")"'
    echo.
    echo Activating the drag^&drop capability for "bashscript" files (only 1 dropped item
    echo will be passed to the script, multiple items are not supported yet)...
    reg add HKEY_CLASSES_ROOT\bashscript\shellex\DropHandler /v "" /t REG_SZ /d "{60254CA5-953B-11CF-8C96-00AA00B8708C}" /f
    

    The "argshandler.sh" script in the Cygwin root just cygpaths back the first argument it receives and nothing at all if there aren't any (e.g. if you just double click on a script file):

    #!/bin/bash
    if [ ! "$1" == "" ]
    then
        cygpath -u "$1"
    fi
    

    All this workes quite nicely so far. However, there are still some drawbacks that would be nice to be resolved:

    • Dragos' command and my derivative of it fail when it comes to scripts that are located on UNC paths, e.g. \\myserver\myshare\scriptfile.sh
    • Only 1 dropped item will be passed to the shell script.

    Somehow, concerning the 1-dropped-item-only issue, changing the argument handler script to give back something like

    "cygpathed-arg1" "cygpathed-arg2" "cygpathed-arg3"
    

    and changing the setter of Dragos' command to something like

    ...; bash "$(cygpath -u "%%1")" $(/argshandler.sh "%%2" "%%3" ... "%%9")'
    

    (note that the "" around the argshandler.sh part are gone) does not seem to work properly: If some of the items dragged onto a script contain a blank in their path, said paths will be broken up into multiple arguments at the blanks even though each of them is enclosed in double quotes ... weird.

    Are there any command line professionals who feel up to it to solve one or both of these issues?

    0 讨论(0)
提交回复
热议问题