windows 下 vscode 使用 msys2 mingw64 作为默认 shell 时识别路径失败

这两天遇到一个 vscode 下 vim 插件的问题(另写一篇文章详述),按照 vscodevim 扩展的构建文档尝试本地调试时,发现无法编译,报如下错误:

1
2
3
正在执行任务: node_modules\.bin\gulp.cmd build-dev
bash: node_modules.bingulp.cmd: 未找到命令
终端进程“C:\msys64\usr\bin\bash.exe '--login', '-i', '-c', 'node_modules\.bin\gulp.cmd build-dev'”已终止,退出代码: 127。

可以看出来是命令找不到,但第二行的报错很奇怪,丢失了 windows 风格路径分隔符 \,查看 vscode 的终端配置发现,我把默认集成终端设置成了 msys2,那么问题很明确了,是因为 msys2 中的 bash 命令不支持 windows 风格的路径分隔符,将其解析为了转义符导致的。

在网上几番搜索皆无果,没有优雅的解决方案,还趁着这个机会认真学习了 vscode 的 launch.json, tasks.json, task provider 等文档,对问题有了一个更深入的了解。

我目前遇到的问题是因为 vscode 自带的 gulp task provider 导致的,当其发现 vscode 在 windows 下运行时,就生成 windows 风格的 gulp 命令路径参数,这在 vscode 使用 cmd 或 powershell 作为默认集成终端时没有问题,但对使用了 bash 作为 shell 的情况就会导致出错了,vscode 的 github 仓库里有几个类似、相关的,已经被关闭并锁定了的 issues:

https://github.com/microsoft/vscode/issues/35593

https://github.com/microsoft/vscode/issues/48149

https://github.com/microsoft/vscode/issues/40954

无意间从 这篇回答中找到了灵感,所以有了如下解决方案,修改 vscode 的配置文件 settings.json,在对集成终端的配置中添加一个自定义终端配置,并将其设置为默认终端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"terminal.integrated.profiles.windows": {
"bash (MINGW64-MSYS2)": {
"path": "C:\\msys64\\usr\\bin\\bash.exe",
"args": [
"--login",
"-i",
"-c",
"if [ -z \"$@\" ]; then bash; else eval \"$(cygpath \"$@\")\"; fi"
],
"env": {
"CHERE_INVOKING": "1",
"MSYSTEM": "MINGW64",
"MSYS2_PATH_TYPE": "inherit"
}
},
// other terminal profiles
// ....
},
"terminal.integrated.defaultProfile.windows": "bash (MINGW64-MSYS2)",

主要是使用了 msys2 中的 cygpath 命令,将文件路径转换为 unix 风格后再继续执行,如果使用 WSL 也可以比葫芦画瓢,但将 cygpath 命令替换为 WSL 中的 wslpath 命令。

这个方法目前我测试用着还行,但还没有长时间使用,不确定是否会带来其他问题,暂且用着吧,如果发现有问题我回来更新此博客。

另外我也在 vscode github 仓库中新建了一个 issue 分享此方法,主要也是希望与别人讨论下此方法是否会带来其他问题:

https://github.com/microsoft/vscode/issues/186119