为什么在 Jenkins 中调用 exit /b 无法正常工作(但其他地方可以)?

6
我有以下问题:我的项目有一个make_all.bat文件,执行多个构建操作,如下所示:
call make_first_component.bat
if %ERRORLEVEL% gtr 0 ( exit /b %ERRORLEVEL% )

call make_second_component.bat
if %ERRORLEVEL% gtr 0 ( exit /b %ERRORLEVEL% )

这个脚本中没有其他额外的代码行(除了echo命令)。

现在,当我通过双击手动调用该脚本,或从命令行调用时,并且make_first_component.bat执行类似于exit /b 1的操作,则make_all.bat按预期退出。

当我从jenkins任务中调用脚本时(如下面的代码),即使第一个组件失败,make_all.bat仍然会继续第二个组件。 如果我以这种方式登录构建从机,并在那里手动启动批处理文件,则如果第一个组件失败,它将退出。

那么,是什么导致Jenkins破坏了%ERRORLEVEL%的概念?

PS:我尝试过setlocal enabledelayedexpansion,然后使用!ERRORLEVEL!,但它总是为0。


注意:Jenkins作业有一个“执行Windows批处理命令”的步骤,如下所示:
cd %WORKSPACE%\src\bat

echo Setting up Visual Studio environment
call "%VS120COMNTOOLS%..\..\VC\vcvarsall.bat" amd64

echo Building Project
call make_all.bat
if %ERRORLEVEL% gtr 0 ( exit /b %ERRORLEVEL% )

(这是完整的步骤)


1
我猜 Jenkins 脚本是一个 *.cmd 文件而不是批处理的 *.bat 文件?混合使用 .bat 和 .cmd 会导致 %errorlevel% 出现问题。 - jeb
你使用的Jenkins版本是什么?@jeb Jenkins会生成一个.bat文件。同时请注意,脚本的最后一行是exit %ERRORLEVEL%,并且通过cmd /c call script.bat进行调用。BatchFile.java源代码 - David Ruhmann
如果在错误级别测试之前放置一行 cd thisDoesntExist,它是否仍然忽略错误级别?当手动设置为像 SET ERRORLEVEL=0 这样的值时,ERRORLEVEL 将失败。 - jeb
你能在所有脚本中设置 @echo on,然后重新运行作业并发布控制台输出吗?只是猜测,但问题可能不在批处理文件上,而是用户权限,因为默认情况下 Jenkins 使用 Local System 用户运行,并且没有管理员访问权限。 - David Ruhmann
@DavidRuhmann:本地系统的令牌包括管理员组,因此在(几乎所有)情况下,它确实具有管理员访问权限。(但也许Jenkins故意创建和使用一个权限较低的令牌?) - Harry Johnston
1个回答

2

当ERRORLEVEL被覆盖时,会出现这种效果。

示例

set errorlevel=0
cd ThisDoesntExist
echo %errorlevel%
set "errorlevel="
echo %errorlevel%

它输出

0
1

结论:使用set "errorlevel="可以恢复正常的%ERRORLEVEL%行为


准确地说,在调用 make_all.bat 之前重置错误级别解决了问题。谢谢 :) - Tim Meyer

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