在 MSYS2/MinGW 中执行脚本

Posted

技术标签:

【中文标题】在 MSYS2/MinGW 中执行脚本【英文标题】:Executing a script in MSYS2/MinGW 【发布时间】:2018-05-06 10:23:01 【问题描述】:

在 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 这有帮助,我可以执行我的脚本,但是 1)环境仍然不一样(例如,它没有找到介子,而它在 mingw64 shell 中找到它),以及 2)它会打开一个新窗口。 我已经发布了我的答案,但我想澄清一下您的“新窗口”投诉。您想要显示任何窗口吗?如果您的脚本有错误并且您想查看错误是什么,会发生什么? @DavidGrayson 感谢您的长回答,我会仔细阅读。关于没有窗口,我想从另一个程序(例如 jenkins)执行脚本并以编程方式检索其输出(就像我对不使用 msys2 的任何“本机”脚本所做的那样)。 您在问题中没有提到这一点。从 Jenkins 运行的命令可能类似于我的答案中的命令,除了您删除 /bin/env 之前的所有内容并将 /bin/env 替换为同一程序的绝对 Windows 样式路径。运行 mintty 可能会阻止您获得输出。 【参考方案1】:

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

C:\msys64\usr\bin\mintty.exe -w hide /bin/env MSYSTEM=MINGW64 /bin/bash -l /c/Users/rom1v/project/release.sh

请注意,这里有 4 条路径。 minttyrelease.sh 的路径是您需要调整的绝对路径。 envbash 的路径是相对于您的 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 hide 仍然没有聚焦当前窗口,至少在我的情况下是这样。我仍在寻找一种解决方案来防止这种情况,让它专注于当前的程序。【参考方案2】:

感谢@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"

【讨论】:

以上是关于在 MSYS2/MinGW 中执行脚本的主要内容,如果未能解决你的问题,请参考以下文章

cmake msys2 mingw无法编译简单的测试程序

msys2+minGW方案编译ffmpeg的最佳实践

windows安装msys2 mingw64

Msys2+mingw-w64 编译VS2013使用的ffmpeg静态库注意事项

MSYS2 MinGW 不包括 mingw-get 包管理器

msys2 (mingw) 默认库/包含路径配置