Jenkins Pipeline执行Windows shell命令失败仍返回0的问题及解决
问题根本原因
1. %errorlevel%始终为0的核心原因
你最初的写法用forfiles命令嵌套调用cmd执行newman,而forfiles本身的退出码仅代表它自身是否成功执行(比如是否找到目标文件、是否正常启动了内部命令),不会透传内部调用的newman进程的非0退出码。只要forfiles本身运行没报错,不管newman执行成功还是失败,forfiles返回给Jenkins bat步骤的退出码都是0,所以阶段会被判定为成功。
2. 日志显示echo 0而非echo %errorlevel%的原因
Jenkins的每一个bat步骤都会独立启动一个新的cmd进程:
- 第一个bat步骤执行完后,对应的cmd进程直接销毁,该进程内的
%errorlevel%变量也会随之消失 - 第二个bat步骤启动的是全新的cmd进程,新进程初始状态无任何错误,所以
%errorlevel%默认值就是0。cmd在执行脚本前会先做变量预解析,把%errorlevel%直接替换为当前值0,所以实际执行的命令就是echo 0,日志自然会打印echo 0。
如何让Pipeline阶段正确识别命令失败
Jenkins的bat/sh步骤默认自带失败判定逻辑:只要收到命令返回的非0退出码,会自动将当前阶段标记为失败,无需额外配置,只需要确保退出码不被嵌套命令吞掉即可,推荐实践方式:
- 避免用
forfiles这类会吞内部命令退出码的工具做批量执行,你已经实现的方案就是最优解法:用Jenkins内置的findFiles遍历目标文件,每个newman任务单独调用bat执行,这样newman的退出码会直接返回给bat步骤,只要newman执行失败返回非0,阶段会立刻标记失败。 - 如果必须在同一个bat步骤内执行多条命令,要手动透传退出码,示例:
bat encoding: 'UTF-8', script: ''' newman run 测试文件1.json -e 配置.json --bail if %errorlevel% neq 0 exit /b %errorlevel% newman run 测试文件2.json -e 配置.json --bail '''
- 同个bat内需要多次读取
%errorlevel%时,要开启cmd延迟变量扩展,用!errorlevel!读取,避免预解析导致的变量值错误。
内容的提问来源于stack exchange,提问作者Jaxx
相关产品推荐
相关产品推荐

