如何在Visual Studio中将Bash Shell脚本作为构建事件运行?

您所在的位置:网站首页 sysnative文件夹 如何在Visual Studio中将Bash Shell脚本作为构建事件运行?

如何在Visual Studio中将Bash Shell脚本作为构建事件运行?

#如何在Visual Studio中将Bash Shell脚本作为构建事件运行? | 来源: 网络整理| 查看: 265

我想在C ++项目中使用Visual Studio中的Build Event的一部分,使用Windows Linux子系统运行Bash shell脚本(.sh)。

但是当我这样做时会出现很多错误,而且我似乎找不到引号,撇号和反斜杠的正确组合以使Bash首先运行或正确地将路径传递给脚本。

如何使Visual Studio作为构建事件运行Bash Shell脚本?

(如果您不关心如何解决问题,只想复制并粘贴命令,请随意跳到该答案的底部!)

好的。

总览

在Visual Studio中,作为Build事件的一部分,我运行了许多Bash shell脚本,并且我以前使用Cygwin来运行它们。现在可以使用适用于Linux的Windows子系统,我花了一些时间将其构建切换为使用WSL,这并不像我希望的那么容易,但是它可以用一点时间和精力来工作。

好的。

如果要执行此操作,将会遇到几个问题:

好的。

bash.exe的路径可能与您想像的不一样,因为在后台,Visual Studio使用32位构建过程,因此,如果您使用的是64位计算机,则不能简单地运行64位计算机。位bash.exe,而不会出现可怕的'C:\\Windows\\System32\\bash.exe' is not recognized错误。 解决方案或项目的路径是Windows路径,该路径使用反斜杠(\\),而在Unix中效果不佳,而Unix则更喜欢使用正斜杠(/)作为路径定界符。 解决方案的根驱动器(通常是C:\\之类的东西)在Unix中毫无意义。要访问WSL中的根驱动器,您需要使用/mnt下的已安装驱动器。 在Windows和WSL之间,驱动器号的大小写有所不同:在Windows中,它是大写的C:\\,在WSL中,它是小写的/mnt/c。

而且,为了使其更难一点,我们不想对任何路径进行硬编码:无论在哪里找到解决方案,它都应该工作。

好的。

好消息是它们都是可以解决的问题!让我们一次解决它们。

好的。

解决问题

1. Bash的正确路径

好的。

根据此处给出的答案,从Visual Studio构建中运行Bash时,需要使用一条魔术路径来到达Bash。正确的路径不是C:\\Windows\\System32\\bash.exe,但实际上是

好的。

1%windir%\\sysnative\\bash.exe

神奇的sysnative文件夹避免了WOW64层执行的不可见文件系统重定向,并指向本机bash.exe文件。

好的。

2.修复反斜杠

好的。

您可能会遇到的下一个问题是反斜杠。理想情况下,您想运行诸如$(ProjectDir)myscript.sh之类的项目脚本,但是它会扩展为诸如C:\\Code\\MySolution\\MyProject\\myscript.sh之类的东西。至少,您希望至少为C:/Code/MySolution/MyProject/myscript.sh,这并不完全正确,但是更接近于更正。

好的。

因此sed进行救援! sed是一个Unix工具,它可以使文件中的文本发生变化:它使用正则表达式搜索文本,并且可以用修改后的版本替换该文本。在这里,我们将把已有的路径传递到sed中,然后使用一些正则表达式魔术来交换路径分隔符,如下所示(为了便于阅读,此处包装了行):

好的。

12%windir%\\sysnative\\bash.exe -c"echo '$(ProjectDir)myscript.sh'     | sed -e 's/\\\\\\\\/\\//g;'"

如果将其作为构建事件包括在内,您将看到它现在不运行脚本,但至少会在输出控制台上输出C:/Code/MySolution/MyProject/myscript.sh之类的信息,这是朝着正确方向迈出的一步。

好的。

是的,要获得正确的转义,要进行很多反斜杠,引号和撇号,因为Nmake.exe和bash和sed在处理它们各自的命令行时都会消耗一些特殊符号。

好的。

3.修复C:\\根路径

好的。

我们想要对sed脚本进行突变,以使其将C:\\变为/mnt/C。更多的正则表达式替代魔术可以做到这一点。 (而且我们必须打开sed中的-r标志,以便我们可以轻松地使用捕获组。)

好的。

12%windir%\\sysnative\\bash.exe -c"echo '$(ProjectDir)myscript.sh'     | sed -re 's/\\\\\\\\/\\//g; s/([A-Z]):/\\/mnt\\/\\1/i;'"

如果运行此命令,您现在将看到类似于/mnt/C/Code/MySolution/MyProject/myscript.sh的输出路径,这几乎但不是很正确。

好的。

4.修复根路径中的大小写更改

好的。

WSL将磁盘安装为小写,Windows将磁盘安装为大写。一致性!我们该如何解决?还有更多sed魔法!

好的。

\\L命令可用于告诉sed将后续字符转换为小写(大写字母也具有等效的\\U)。 \\E命令会将输出切换回"普通"模式,在该模式下,字符保持不变。

好的。

最后添加这些将导致输出正确的路径:

好的。

12%windir%\\sysnative\\bash.exe -c"echo '$(ProjectDir)myscript.sh'     | sed -re 's/\\\\\\\\/\\//g; s/([A-Z]):/\\/mnt\\/\\L\\1\\E/i;'"

5.运行

好的。

在整个过程中,Bash一直在打印脚本的路径。现在这是正确的路径,我们如何运行它?

好的。

答案是添加"反引号"!反引号使Bash执行其中包含的命令,然后将该命令的输出用作下一个命令的参数。在这种情况下,我们将不输出任何内容:我们只想将sed的输出作为命令运行。

好的。

因此,包括反引号在内,结果如下:

好的。

12%windir%\\sysnative\\bash.exe -c"`echo '$(ProjectDir)myscript.sh'     | sed -re 's/\\\\\\\\/\\//g; s/([A-Z]):/\\/mnt\\/\\L\\1\\E/i;'`"

完整的解决方案

这是整个解决方案的外观,用于在当前解决方案的当前Project目录中运行名为myscript.sh的脚本作为Build Event:

好的。

1%windir%\\sysnative\\bash.exe -c"`echo '$(ProjectDir)myscript.sh' | sed -re 's/\\\\\\\\/\\//g; s/([A-Z]):/\\/mnt\\/\\L\\1\\E/i;'`"

这是一个屏幕截图,显示了在Visual Studio 2017中用于真实C ++项目的相同内容:

好的。

好的。

这并不容易,但并非不可能。

好的。

好。

如果您安装了Windows版Git,请尝试此操作。我发现它比安装WSL更简单。基本思想是使用批处理脚本中Git bash的内置bash或sh命令创建一个中间批处理脚本来调用bash脚本。

使用Windows版Git,您将拥有一个Git\\bin文件夹,例如在:

1C:\\Program Files\\Git\\bin

在该目录中,您应该看到bash.exe和sh.exe程序。因此,如果将该目录添加到Windows Path环境变量中,则可以从Windows命令行使用sh和bash。这些命令将允许您在CMD控制台窗口中"内联"运行bash脚本。也就是说,他们不会产生新的bash窗口;这意味着控制台输出将在您的VS版本中可见。

从那里,只需创建一个.bat文件,即可使用sh命令或bash命令调用.sh文件。不确定差异;我们只使用sh命令。因此,如果您的bash脚本是pre.sh,那么您的批处理文件将只是调用bash脚本的一行:

1234sh %~dp0\\pre.sh if errorlevel 1 (    exit /b %errorlevel% )

%~dp0假定批处理脚本和bash脚本位于同一目录中。然后,将VS构建事件指向.bat文件。必须检查错误级别,以便将bash脚本中的所有失败转发至批处理脚本。请参阅:如何从Windows命令行获取应用程序退出代码?

要将其作为VS2019中的构建事件进行挂钩,只需遵循用于挂钩.bat文件的标准说明即可:https://docs.microsoft.com/zh-cn/visualstudio/ide/specifying-custom-build- events-in-visual-studio?view = vs-2019。

更新:当心Visual Studio(VS)的路径变量行为

我们发现对此解决方案感到沮丧的是VS未能正确加载path变量的趋势。似乎更喜欢用户变量而不是系统变量。但是即使删除了用户变量,有时VS似乎也没有选择该路径,并且在构建控制台上仍然不断收到"无法识别sh ..."消息。每当发生这种情况时,重新启动VS似乎都能解决问题。不是很令人满意,但是它可以使我们满意。

更新:这不是完整的Unix解决方案

Windows的Git确实有很多Unix命令可用,但不是全部。因此,总的来说,这是行不通的。对于一般情况,WSL更为健壮。但是,如果您只需要非常轻量级的Unix,那么就足够了,对于Windows用户而言,这可能是一种更简单的方法,他们宁愿避免安装完整的WSL所花费的安装成本。

使用Git bash的最初想法来自这里:https://superuser.com/questions/1218943/windows-command-prompt-capture-output-of-bash-script-in-one-step

相关讨论 那也不是一个不好的解决方案,但是它确实将您限制在Git-for-Windows软件包中安装的命令中。 该软件包包含许多最常见的命令(甚至是perl!); 但是它仍然不是完整的Unix发行版,因此,如果您希望其中包含任何Unix工具,则需要自己编译它们,或者考虑使用WSL。 就是说,这种解决方案对于没有Unix经验或不愿意安装完整Unix发行版的团队来说非常有效,因为安装Windows版Git非常容易。

您可以使用$(和)来包装命令,而不用反引号



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3