在MSYS2/MinGW中执行脚本

20

在Windows下,如果我启动c:\msys64\mingw64.exe,它会打开一个shell,我可以在其中构建我的项目,例如通过调用release bash脚本(为了简单起见)。一切都工作得很好。

现在,我想直接在mingw64上执行我的release脚本,而不需要交互。

我尝试过:

c:\msys64\mingw64.exe /c/the/full/path/release

一个窗口打开并关闭,它不起作用。

我尝试直接使用bash,但似乎环境没有正确设置:

> c:\msys64\usr\bin\bash -c ls
/usr/bin/bash: ls: command not found

> c:\msys64\usr\bin\bash -c /bin/ls
... it works ...

很明显,执行c:\msys64\mingw64.exe再调用ls时,环境已经不同了。

如何在启动mingw64.exe的shell中执行我的release脚本呢?


尝试这个:msys2_shell.cmd -mingw64 -c "help |more" - KonstantinL
@KonstantinL 这很有帮助,我可以执行我的脚本,但是1)环境仍然不同(例如它找不到meson,而在mingw64 shell中可以找到),2)它会打开一个新窗口。 - rom1v
我已经发布了我的答案,但我想要一些关于你的“新窗口”投诉的澄清。你是否希望任何窗口都不会出现?如果你的脚本出现错误,你想查看错误是什么会发生什么? - David Grayson
@DavidGrayson 谢谢你的长篇回答,我会仔细阅读。关于没有窗口的问题,我想从另一个程序(例如jenkins)执行脚本,并以编程方式检索其输出(就像我使用任何不使用 msys2 的“本机”脚本一样)。 - rom1v
1
你在问题中没有提到这一点。从Jenkins运行的命令可能类似于我的答案,除了你需要删除/bin/env之前的所有内容,并将/bin/env替换为相同程序的绝对Windows风格路径。运行mintty可能会阻止你获取输出。 - David Grayson
你说得对,我的问题没有表述清楚。我只想提供最少的信息,以避免许多无关的细节。非常感谢! - rom1v
4个回答

20

要在MSYS2中运行Bash shell脚本而不显示窗口,您应该右键单击桌面或Windows Explorer中的其他位置,选择“新建”,选择“快捷方式”,然后为快捷方式目标输入类似以下内容:

C:\msys64\usr\bin\mintty.exe -w hide /bin/env MSYSTEM=MINGW64 /bin/bash -l /c/Users/rom1v/project/release.sh
注意这里有4个路径。到 mintty release.sh 的路径是绝对路径,您需要调整它们。到 env bash 的路径相对于您的MSYS2安装目录。还要注意,第一个路径必须是标准的Windows路径,因为Windows在运行快捷方式时期望如此。
MinTTY可能看起来很奇怪,因为它是为Windows子系统编译的(使用GCC的-mwindows选项)但我们需要使用一些程序,否则Windows将在运行程序时自动启动新控制台。 我们传递-w hide选项给MinTTY,告诉它不要显示窗口。之后的所有内容都被MinTTY解释为要运行的命令。
所以MinTTY将从MSYS2分发中运行/bin/env并将其余的参数传递给它。这是一个方便的实用程序,实际上是Linux和MSYS2的标准部分。它将MSYSTEM环境变量设置为MINGW64(稍后很重要),然后使用剩余的命令行参数运行/bin/bash
我们传递-l给Bash,使其作为登录脚本,并运行某些启动脚本。特别是来自MSYS2的/etc/profile脚本至关重要,因为它查看MSYSTEM环境变量,看到它是MINGW64,然后设置了一堆其他环境变量(例如PATH),以提供MinGW 64位shell环境。
最后,我们将您的脚本名称作为bash的主参数传递,因此在运行初始化脚本后它将运行该脚本。
请注意,如果您的Bash脚本出现错误,您将不会收到任何通知,因为上面的快捷方式不会打开任何控制台窗口。我个人觉得这非常烦人。我可能会删除-w hide选项,然后制作一个包装Bash脚本,只需执行以下操作:
run_my_main_script || sleep 10000
所以如果主脚本成功,立即退出,否则保持窗口打开10000秒。您甚至不必将包装器脚本放在自己的文件中,您可以将其作为Bash的-c选项的参数放入快捷方式中(不要忘记用双引号括起来)。

请注意,-w隐藏仍会取消当前窗口的焦点,至少在我的情况下是这样。我仍在寻找解决方法,以防止它失去对其当前程序的关注。 - Menno van Leeuwen

8

感谢@David Grayson的答案,我成功地在Windows控制台(cmd)中使用msys2/mingw调用了我的release脚本,并且在$PATH中添加了额外的目录(Java和Meson):

c:\msys64\usr\bin\env MSYSTEM=MINGW64 c:\msys64\usr\bin\bash -l -c "PATH=\"/c/Program Files/Java/jdk1.8.X_XXX/bin:/c/Program Files/Meson:$PATH\" /c/Users/rom1v/project/release"

4
另一种方法是使用MSYS2安装文件夹中的msys2_shell.cmd启动器。假设它被安装到默认文件夹,则命令如下:
C:\msys64\msys2_shell.cmd -defterm -no-start -mingw64 -here -c "your command here"

选项-defterm将输出发送到当前终端,-no-start使新的终端窗口不会打开,-here将当前目录设置为工作目录,-mingw64是要使用的环境(其他可能性包括-mingw32-ucrt64-clang64),-c是您的shell命令本身。

谢谢,Tiago。你是从哪里学到这些命令行参数的知识的? - daveloyall

0
在上面添加一个补充说明:如果您想要 shell 脚本的输出。
  • reference:https://mintty.github.io/mintty.1.html
-l,--log FILE|-
将所有输出复制到指定的日志文件中,或者如果给出一个短横线而不是文件名,则复制到标准输出。 (意味着-o Logging=yes)。
如果文件名包含%d,则将其替换为进程ID。有关更多格式选项和提示,请参见等效选项“日志文件”(Log =)的描述。
请注意,可以从扩展上下文菜单切换日志记录。
完整示例: C:\msys64\usr\bin\mintty.exe -w hide -l - c:\msys64\usr\bin\env MSYSTEM=MINGW64 c:\msys64\usr\bin\bash -l -c "PATH=\"$PATH\" /C/Users/Administrator/Desktop/myProject/Demo_C_C++/shell/textProcess/bookNoteHandler.sh" | find /v "/v:Displays all lines that don't contain the specified"

=========

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接