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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/105075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 05:20:21  来源:igfitidea点击:

How can I associate .sh files with Cygwin?

windowsbashcygwin

提问by Jerph

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?

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

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

注意:我刚刚在这里找到一个 Cygwin 包,用于管理 Windows 上下文菜单(此处为 Bash Prompt)。它可能有一些线索。

采纳答案by Jerph

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

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

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

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

You may also want to add SHto your PATHEXTenvironment variable:

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

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

WinKey+暂停/高级/环境变量/系统变量/PATHEXT

Thanks for your help, guys!

感谢您的帮助,伙计们!

回答by Jerph

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.

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

assoc .sh=bashscript

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

回答by eomanis

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.

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

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).

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

The .bat file roughly goes as follows:

.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

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):

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

#!/bin/bash
if [ ! "" == "" ]
then
    cygpath -u ""
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.
  • 当涉及位于 UNC 路径上的脚本(例如 \\myserver\myshare\scriptfile.sh)时,Dragos 的命令及其派生的命令会失败
  • 只有 1 个丢弃的项目会被传递给 shell 脚本。

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

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

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

and changing the setter of Dragos' command to something like

并将 Dragos 命令的 setter 更改为类似

...; 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.

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

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

是否有任何命令行专业人员能够解决这些问题中的一个或两个?

回答by eomanis

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.

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

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

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

"C:\cygwin\bin\mintty.exe" -w max -h always -t "%1" -e /bin/bash -li -c 'printf "3]0;$(cygpath -u "%1")
@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
7" && cd "$(dirname "$(cygpath -u "%1")")" && bash "$(cygpath -u "%1")"'

Batch scripts to set the association for you:

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

Windows path in title:

标题中的 Windows 路径:

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

And cygwin path in title:

和标题中的cygwin路径:

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

回答by Light93

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

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

$ cat test.bat
@echo off

set MYDIR=C:\scripts

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

to,

到,

cd `dirname "
C:\Dev\scripts\cygbashrun.bat
"`

回答by David

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:

这不会关联 .sh 文件,但它可能会让你得到你想要的。我从启动 Cygwin bash shell 的 cygwin.bat 批处理文件开始,并像这样修改它:

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

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.

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

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.

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

回答by Sparr

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:

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

    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 

回答by HaveAGuess

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

我使用 PuttyCyg(Cygwin 窗口中的很棒的腻子)以下是如何让它全部进行:

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

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

@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

with contents

有内容

##代码##

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

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

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

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

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

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

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

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

Then:

然后:

  1. New..
  2. Action = Run Bashscript..
  3. Application used to perform this action = C:\Dev\scripts\cygbashrun.bat "%1"
  1. 新的..
  2. 操作 = 运行 Bashscript ..
  3. 用于执行此操作的应用程序 = C:\Dev\scripts\cygbashrun.bat "%1"

Works like a charm for me :O)

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

回答by Yordan Georgiev

##代码##

回答by Johnny Wong

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:

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

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

=== 文件 run-script-with-Cygwin-in-same-dir.bat ===

##代码##

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

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

Enjoys :)

喜欢:)