如何将 .sh 文件与 Cygwin 关联?

发布于 2024-07-04 19:34:36 字数 341 浏览 8 评论 0原文

我想通过双击 Windows 中的 .sh 文件来在 Cygwin 中运行长 rsync 命令。 它必须从文件所在的目录(例如/cygdrive/c/scripts/)开始,以便相对路径起作用。 有人得到这个工作吗?

注意:我刚刚找到 这里,一个管理 Windows 上下文菜单的 Cygwin 包(这里是 Bash Prompt)。 或许能看出一些端倪。

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 that relative paths work. Anyone gotten this to work?

Note: I've just found here, a Cygwin package that manages Windows context menus (Bash Prompt Here). It might have some clues.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

送你一个梦 2024-07-11 19:34:36

查看 dos 框中的 assoc 和 ftype 命令。
这是我机器上的 .jpg 示例

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"

确保您在 ftype 命令中更改了 bash 的路径,以匹配您的 cygwin已安装

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

雪花飘飘的天空 2024-07-11 19:34:36

我自己开发了一个.bat脚本(不是源自其他人的答案)来关联文件类型(例如*.cygwin)以与此.bat打开,如下所示:

=== file run-script-with-Cygwin-in -same-dir.bat ===

@echo off
REM   Info: A script created by Johnny Wong.  (last modified on 2014-7-15)
REM   It is used to pass a file argument to run a bash script file.  The current directory is setting to the path of the script file for convenience.
REM   Could be copied to C:\cygwin;  and then you manually associate .cygwin file extension to open with this .bat file.
set CYGWIN=nodosfilewarning

C:\cygwin\bin\bash --login -i -c 'cd "`dirname "%~1"`"; exec bash "%~1" %2 %3 %4 %5 %6 %7 %8 %9'

REM finally pause the script (press any key to continue) to keep the window to see result
pause

=== file run-script-with-Cygwin-in-same-dir.bat === 有关

所用语法的详细说明(如果您有兴趣):

  1. %1 是“... " 如果与要使用此 .bat 打开的文件关联,则引用。 要将文件拖动到此 .bat,仅当文件路径包含空格时才用“...”引用。
  2. %~1 与 %1 相同,但删除了周围的双引号,如果存在
  3. 从 %p% 删除周围的双引号,请使用 for %%a in (%p%) do set p=%%~ a
  4. 您必须使用 "%~1" 强制脚本文件的路径用双引号引起来,以便 bash 不会删除其文件夹分隔符 '\'(在 %1 中)当被视为转义字符时。 否则,将路径中没有空格的文件拖到此 .bat 时将不起作用。
  5. “exec bash”可以只是“bash”,前者是为了节省资源以供多一个bash进程使用。

喜欢:)

I developed a .bat script on my own (not originated from other's answer) to associate a file type (e.g. *.cygwin) to open with this .bat, as follows:

=== file run-script-with-Cygwin-in-same-dir.bat ===

@echo off
REM   Info: A script created by Johnny Wong.  (last modified on 2014-7-15)
REM   It is used to pass a file argument to run a bash script file.  The current directory is setting to the path of the script file for convenience.
REM   Could be copied to C:\cygwin;  and then you manually associate .cygwin file extension to open with this .bat file.
set CYGWIN=nodosfilewarning

C:\cygwin\bin\bash --login -i -c 'cd "`dirname "%~1"`"; exec bash "%~1" %2 %3 %4 %5 %6 %7 %8 %9'

REM finally pause the script (press any key to continue) to keep the window to see result
pause

=== file run-script-with-Cygwin-in-same-dir.bat ===

Detail explanations on syntax used (if you are interested) :

  1. %1 is "..." quoted if associated a file to open with this .bat. For dragging a file to this .bat, it is "..." quoted only if the file's path has spaces.
  2. %~1 is same as %1 with surrounding double-quotes eliminated, if they exist
  3. to remove surrounding double-quotes from %p%, use for %%a in (%p%) do set p=%%~a
  4. you must use "%~1" to force the script file's path double-quoted, so that its folder separators '\' (in %1) won't be removed by bash when being treated as escape characters. Otherwise, it does not work when dragging a file, which has no spaces in its path, to this .bat.
  5. "exec bash" can be just "bash", the former is for saving resources for one more bash process.

Enjoys :)

明媚如初 2024-07-11 19:34:36

一种可行的解决方案是创建一个 .bat 文件,该文件将打开 cygwin 并执行您的脚本。

执行位于我的主目录中的脚本 go.sh 的脚本:

@echo off

C:
chdir C:\cygwin\bin

bash --login -i ./go.sh

One solution that works is to create a .bat file that will open cygwin and execute your script.

The script to execute the script go.sh located on my home directory:

@echo off

C:
chdir C:\cygwin\bin

bash --login -i ./go.sh
泪之魂 2024-07-11 19:34:36

我只是没打扰。 我将 .sh 文件与 Crimson Editor 相关联(因为我花在解决错误上的时间与实际运行它们的时间一样多)。 现在的问题是让正确的“打开方式/编辑方式”组合在“文件类型”>“高级”中工作。 如果我知道 Crimson Editor 使用的 DDE 代码,事情就会变得更容易; 然而,截至这篇文章我还没有找到它。

这让我想起了我在 Mac 上的日子(1993-2008 年),当时我常常尝试扫描应用程序以获取基本的 AppleScript 脚本能力。

BZT

I just didn't bother. I associated .sh files with Crimson Editor (since I spend as much time working out the bugs as I do actually running them). Now it's a matter of getting the right "open with/edit with" combination to work in File Types>Advanced. If I knew what DDE code Crimson Editor used, that would make things easier; as of this post I've not been able to find it, however.

This reminds me of my Mac days (1993-2008) when I used to try and scan applications for more than rudimentary AppleScript scriptability.

BZT

失去的东西太少 2024-07-11 19:34:36
    Windows Registry Editor Version 5.00
    ;File:ConfigureShToBeRunUnderExplorer.reg v:1.0 docs at the end
    [HKEY_CLASSES_ROOT\Applications\bash.exe] 

    [HKEY_CLASSES_ROOT\Applications\bash.exe\shell]

    [HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open]

    [HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open\command]
    @="C:\\cygwin\\bin\\bash.exe -li \"%1\" %*"

    ; This is a simple registry file to automate the execution of sh via cygwin on windows 7, might work on other Windows versions ... not tested 
    ; you could add this setting by issueing the following command: reg import ConfigureShToBeRunUnderExplorer.reg 
    ; Note the path of your bash.exe
    ; Note that you still have to add the .sh to your %PATHTEXT%
            ; usage: double - click the file or reg import file 
    Windows Registry Editor Version 5.00
    ;File:ConfigureShToBeRunUnderExplorer.reg v:1.0 docs at the end
    [HKEY_CLASSES_ROOT\Applications\bash.exe] 

    [HKEY_CLASSES_ROOT\Applications\bash.exe\shell]

    [HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open]

    [HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open\command]
    @="C:\\cygwin\\bin\\bash.exe -li \"%1\" %*"

    ; This is a simple registry file to automate the execution of sh via cygwin on windows 7, might work on other Windows versions ... not tested 
    ; you could add this setting by issueing the following command: reg import ConfigureShToBeRunUnderExplorer.reg 
    ; Note the path of your bash.exe
    ; Note that you still have to add the .sh to your %PATHTEXT%
            ; usage: double - click the file or reg import file 
凉城已无爱 2024-07-11 19:34:36

我使用 PuttyCyg(Cygwin 窗口中很棒的腻子),以下是如何实现这一切:

创建一个批处理脚本,例如。 在我的机器上,我使用的

C:\Dev\scripts\cygbashrun.bat

内容

SET CYGWIN=nodosfilewarning
C:\Cygwin\bin\putty.exe -cygterm /bin/bash.exe %1

显然适应包含 PuttyCyg 安装的路径。

然后在 Windows 文件资源管理器中,转到“工具”-“文件夹选项”-“文件类型”

如果还没有“.sh”条目(或 .bash,具体取决于您希望脚本具有的内容),则创建一个“.sh”条目。然后是“高级”..

[可选步骤] 更改图标并从安装中选择 Cygwin 图标

然后:

  1. New..
  2. Action = Run Bashscript..
  3. 用于执行此操作的应用程序 = C:\Dev\scripts\cygbashrun.bat "%1"

对我来说就像一个魅力:O)

I use PuttyCyg (awesome putty in Cygwin window) here's how to get it all going:

Create a batch script, eg. on my machine I used

C:\Dev\scripts\cygbashrun.bat

with contents

SET CYGWIN=nodosfilewarning
C:\Cygwin\bin\putty.exe -cygterm /bin/bash.exe %1

Obviously adapt to contain the paths of your install of PuttyCyg.

Then in Windows File Explorer go to Tools - Folder Options - File Types

Create a ".sh" entry if there isn't already (or .bash depending on what you like your scripts to have).. then Advanced..

[optional step] change the icon and select the Cygwin icon from your install

Then:

  1. New..
  2. Action = Run Bashscript..
  3. Application used to perform this action = C:\Dev\scripts\cygbashrun.bat "%1"

Works like a charm for me :O)

猫七 2024-07-11 19:34:36

您应该能够将 .sh 文件与 \CYGWIN\usr\bin\bash.exe 关联。 该脚本必须更改其自己的工作目录,我建议在顶部粘贴类似的内容:

cd `dirname "$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"`
☆獨立☆ 2024-07-11 19:34:36

看了不同的地方之后。 我设法想出的是,首先从 Windows“打开方式...”对话框中选择 C:\cygwin64\bin\mintty.exe
然后编辑注册表值

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

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\" %*"  

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\" %*"  
勿忘初心 2024-07-11 19:34:36

这是我正在使用的命令:

"C:\cygwin\bin\mintty.exe" -w max -h always -t "%1" -e /bin/bash -li -c 'cd "$(dirname "$(cygpath -u "%1")")" && bash "$(cygpath -u "%1")"'

它在 mintty 中运行它,最大化,将窗口标题设置为正在运行的脚本(它的 Windows 路径),将目录更改为脚本所在的位置,运行它并在完成后保持打开状态。

或者,这会将标题设置为脚本的 cygwin 路径:

"C:\cygwin\bin\mintty.exe" -w max -h always -t "%1" -e /bin/bash -li -c 'printf "\033]0;$(cygpath -u "%1")\007" && cd "$(dirname "$(cygpath -u "%1")")" && bash "$(cygpath -u "%1")"'

为您设置关联的批处理脚本:

标题中的 Windows 路径:

@echo off
assoc .sh=shellscript
ftype shellscript="C:\cygwin\bin\mintty.exe" -w max -h always -t "%%1" -e /bin/bash -li -c 'cd "$(dirname "$(cygpath -u "%%1")")" ^&^& bash "$(cygpath -u "%%1")"'
pause

标题中的 cygwin 路径:

@echo off
assoc .sh=shellscript
ftype shellscript="C:\cygwin\bin\mintty.exe" -w max -h always -t "%%1" -e /bin/bash -li -c 'printf "\033]0;$(cygpath -u "%%1")\007" ^&^& cd "$(dirname "$(cygpath -u "%%1")")" ^&^& bash "$(cygpath -u "%%1")"'
pause

This is the command I'm using:

"C:\cygwin\bin\mintty.exe" -w max -h always -t "%1" -e /bin/bash -li -c 'cd "$(dirname "$(cygpath -u "%1")")" && bash "$(cygpath -u "%1")"'

It runs it in mintty, maximised, sets the window title to the script being ran (Windows path to it), changes directory to where the script is, runs it and stays open after it completes.

Alternatively, this will set the title to the cygwin path to the script:

"C:\cygwin\bin\mintty.exe" -w max -h always -t "%1" -e /bin/bash -li -c 'printf "\033]0;$(cygpath -u "%1")\007" && cd "$(dirname "$(cygpath -u "%1")")" && bash "$(cygpath -u "%1")"'

Batch scripts to set the association for you:

Windows path in title:

@echo off
assoc .sh=shellscript
ftype shellscript="C:\cygwin\bin\mintty.exe" -w max -h always -t "%%1" -e /bin/bash -li -c 'cd "$(dirname "$(cygpath -u "%%1")")" ^&^& bash "$(cygpath -u "%%1")"'
pause

And cygwin path in title:

@echo off
assoc .sh=shellscript
ftype shellscript="C:\cygwin\bin\mintty.exe" -w max -h always -t "%%1" -e /bin/bash -li -c 'printf "\033]0;$(cygpath -u "%%1")\007" ^&^& cd "$(dirname "$(cygpath -u "%%1")")" ^&^& bash "$(cygpath -u "%%1")"'
pause
挖个坑埋了你 2024-07-11 19:34:36

这不会关联 .sh 文件,但它可能会为您提供所需的内容。 我从启动 Cygwin bash shell 的 cygwin.bat 批处理文件开始,并对其进行了如下修改:

$ cat test.bat
@echo off

set MYDIR=C:\scripts

C:\cygwin\bin\bash --login -c "cd $MYDIR && echo 'Now in' `pwd`; sleep 15"

这是一个玩具脚本,但您可以修改它以调用 rsync 或调用单独的 shell 脚本。 我承认如果没有 MYDIR 硬编码的话会更好。 可能有一种方法可以让它自动设置它。

哦,是的,当我在 Cygwin 的 bash shell 中创建 .bat 文件时,我注意到我实际上必须“chmod +x test.bat”才能通过双击启动它。 我认为这是设置NTFS权限。 如果您只使用记事本,则不需要这样做。

This doesn't associate .sh files, but it might get you what you want. I started with the cygwin.bat batch file that launches the Cygwin bash shell, and modified it like so:

$ cat test.bat
@echo off

set MYDIR=C:\scripts

C:\cygwin\bin\bash --login -c "cd $MYDIR && echo 'Now in' `pwd`; sleep 15"

That's a toy script but you could modify it to call rsync or call a separate shell script. I admit that it would be nicer if it didn't have MYDIR hard coded. There's probaby a way do get it to automagically set that.

Oh yeah, when I created the .bat file in a bash shell in Cygwin, I noticed I had to actually "chmod +x test.bat" before I could launch it with a double-click. I think it's setting NTFS permissions. You wouldn't need to do that if you just used notepad.

琴流音 2024-07-11 19:34:36

这是我的解决方案。 它非常适合我的 *.sh 脚本
无论它们位于目录层次结构中的哪个位置。
请注意,我在调用之前 cd 到 cygpath 目录名
在 cygpath 上执行 bash。 它就是有效的。

assoc .sh=bashscript

ftype bashscript=C:\cygwin\bin\bash.exe --login -i -c 'cd "$(dirname "$(cygpath -u "%1")")"; bash "$(cygpath -u "%1")"'

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")"'

我使用 Dragos 的解决方案已经有一段时间了,我认为它是最好的解决方案,因为它消除了在 shell 脚本中使用“cygpath -u”的需要。

然后我想要其他功能,例如对 .sh 和 .bash 文件的拖放支持。 经过一番研究后,我编写了一个 .bat,它将 .sh 和 .bash 文件关联为“bashscript”,并为它们激活 Windows 资源管理器拖放处理程序。 我必须编辑 Dragos 的命令以使其处理 1 个参数(放置在 shell 脚本上的项目的路径)。

.bat 文件大致如下:

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

Cygwin 根目录中的“argshandler.sh”脚本只是 cygpaths 返回它收到的第一个参数,如果没有任何参数,则什么也不做(例如,如果您只是双击脚本文件) :

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

到目前为止,所有这些都运行得很好。 然而,仍然存在一些需要解决的缺点:

  • 当涉及位于 UNC 路径上的脚本时,Dragos 的命令和我的派生命令会失败,例如 \\myserver\myshare\scriptfile.sh
  • Only 1 Droped Item将被传递到 shell 脚本。

不知何故,关于仅 1-dropped-item 的问题,更改参数处理程序脚本以返回类似的内容

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

,并将 Dragos 命令的设置器更改为类似的内容

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

(请注意,argshandler.sh 部分周围的“”消失了)似乎无法正常工作:如果拖到脚本上的某些项目在其路径中包含空格,则所述路径将在空格处分解为多个参数,即使每个参数都用双引号引起来......很奇怪。

是否有任何命令行专业人员愿意解决其中一个或两个问题?

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?

用心笑 2024-07-11 19:34:36

好的,我找到了有用的东西。 按照弗拉基米尔的建议关联批处理文件不起作用,但 bash 参数是关键。

简短而甜蜜:与此命令相关联:"C:\cygwin\bin\bash.exe" -li "%1" %*

如果您不知道如何操作,则长版本:

  1. 在资源管理器中,转到到工具/文件夹选项/文件类型。
  2. 我已经有了 Bash 脚本的 SH 条目。 如果您没有,请单击“新建”并输入“SH”来创建一个。
  3. 选择 SH 扩展名后,单击“高级”。
  4. 选择“打开”操作并单击编辑(或创建操作)。
  5. 这是要使用的命令:"C:\cygwin\bin\bash.exe" -li "%1" %*。 请注意,如果没有 -li,它会在我的脚本中返回“未找到命令”。

您可能还想将 SH 添加到您的 PATHEXT 环境变量中:

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

感谢您的帮助,伙计们!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文