我可以调用%COMSPEC%而不终止所有Windows批处理执行吗?

dy2hfwbg  于 2023-01-31  发布在  Windows
关注(0)|答案(2)|浏览(154)

我在Jenkins管道中尝试自动化的系统构建过程中遇到了批处理行为的这种奇怪现象。
直接跳到问题的实质以及我遇到它的原因,我调用的批处理文件是一个构建生成的批处理文件,必须在同一命令窗口中的另一个可执行文件之前调用它,以便为构建系统的可执行文件设置路径等。然后运行可执行文件。但是在Jenkins中我必须将所有命令作为一个批处理文件有效地传递,才能使它在同一个窗口中调用,除非我想用Withenv之类的东西手动配置所有这些路径。
在我的Jenkins时髦剧本里沿着这样一句话:

// Option 1 - && operator
bat "env_configuration.bat && env_dependent_exec.exe"

// Option 2 - multi line version
bat """env_configuration.bat
env_dependent_exec.exe
"""

// Option 3 - same using calls, yadda yadda
bat """call env_configuration.bat
call env_dependent_exec.exe
"""

// Option 4 - Place these calls in batch file and call that instead
bat "run_it_all.bat"

但是,作为批处理文件的一部分,无论出于何种原因,它都包含此命令。

%COMSPEC%
exit /b 0

这将调用“C:\WINDOWS\system32\cmd.exe”并输出Microsoft版本和相关简介。例如:
微软 windows [版本10.0.19045.2486](c)微软公司。保留所有权利。
问题是,调用此可执行文件将立即结束所有批处理的执行。“exit /b 0”行实际上并没有被命中,我想创建此进程的人从未意识到这一点。此批处理文件进程完成后,所有后续命令/调用,(上面的选项1是最容易重现的)不会被命中,因为所有的批处理都停止了。这在cmd本身中是直接可见的,你不需要Jenkins来繁殖。
我可能会找到并替换这一行来注解掉它或其他什么...但我不相信我找不到某种方法来阻止%COMSPEC%结束任何批处理文件调用它的所有执行。如果让我猜的话,我会猜cmd.exe在完成时调用EXIT并杀死所有...
出于兴趣,我尝试用多种方法修改批处理文件,看看是否可以调用%COMSPEC%,然后仍然运行批处理脚本的其余部分。

:: This fails the same way
call %COMSPEC%
exit /b 0

:: This succeeds to run, but spawns another cmd window that doens't print in the original calling batch file output, so doesn't achieve the original goal
start %COMSPEC%
exit /b 0

:: call %COMSPEC% via subroutine also immediately terminates, we never see "echo 2"
call :comspec_call
exit /b 0

:comspec_call
@echo %COMSPEC% echo 1
%COMSPEC%
@echo %COMSPEC% echo 2

我猜cmd.exe在终止时调用EXIT命令,因此进程死亡,但我还没有找到一种方法来阻止它这样做...
我已经检查了%COMSPEC%中的标志,这些标志可能只是打印输出并很好地终止,但我发现的任何提供此信息的标志也都以EXIT终止(我认为)
有没有人知道如何调用这行代码并继续执行,就像我假设的原始开发意图一样?提前干杯!

unftdfkk

unftdfkk1#

批处理并不只是"停止"--你已经启动了"另一个"命令解释器,而启动它的解释器正在"等待"新示例终止。由于它没有退出,一切似乎都停止了,你最终杀死了这两个解释器,让事情恢复正常。
创建一个执行以下操作的新批处理脚本:

:: controller.bat
@echo off
call env_configuration.bat
call some_other.bat
env_dependent_exec.exe
...

使用call命令会导致命令shell调用 * 使用当前解释器 * 的脚本。
现在,您的Jenkins groovy脚本应该是:

bat controller.bat

(免责声明:我不认识Jenkins,所以......)

frebpwbc

frebpwbc2#

感谢@Duthomhas和@Magoo
这里的问题是调用%COMSPEC%会启动一个新的命令行进程,该进程必须在脚本的其余部分继续之前终止。我不明白cmd.exe正在生成一个新脚本,而调用脚本正在等待终止。
简单回顾一下:

:: env_configuration.bat
@echo env_configuration before COMSPEC
@%COMSPEC%
@echo env_configuration after COMSPEC

:: controller.bat
@echo controller before env_configuration.bat
@call env_configuration.bat
@echo controller after env_configuration.bat

controller.bat && @echo back in shell

当你运行controller.bat时,进程将输出Microsoft blurb,但会停止。如果你在此时输入“exit”,它将退出用%COMSPEC%启动的终端,然后所有后续脚本步骤继续。
我还没有弄清楚如何实现这是一个单一的命令行调用呢...但至少我现在知道发生了什么!干杯!

相关问题