Jenkins声明式流水线:如何忽略返回状态获取Bat脚本输出?
问题描述
尝试获取bat脚本的输出,无论其返回状态如何,使用了以下代码:
String spectralOutput try { spectralOutput = bat(script: ''' @spectral lint \"%WORKSPACE%\\\\SelfContained\\\\*.json\" --ruleset \"%WORKSPACE%\\\\spectral\\\\.spectral.json\" ''', returnStdout: true, encoding: 'UTF-8') } catch (hudson.AbortException e) { spectralOutput = spectralOutput.replace('\n', '<br>') // Parse Spectral output if (!spectralOutput.contains('0 errors')) { echo spectralOutput currentBuild.result = 'FAILED' } echo spectralOutput }
运行时出现错误:
java.lang.NullPointerException: Cannot invoke method replace() on null object
推测当bat脚本返回错误退出码时会抛出异常,导致spectralOutput未被赋值。需要解决:
- 无论退出码如何,将输出存入
spectralOutput的方法 - 是否需要通过重定向到文本文件读取输出
returnStatus和returnStdout无法同时使用的处理方案
解决方案
方法1:修改bat脚本强制返回0退出码
在bat脚本末尾添加exit 0,让脚本无论执行结果如何都返回成功,避免bat步骤抛出异常,直接捕获标准输出:
String spectralOutput = bat(script: ''' @spectral lint \"%WORKSPACE%\\\\SelfContained\\\\*.json\" --ruleset \"%WORKSPACE%\\\\spectral\\\\.spectral.json\" exit 0 ''', returnStdout: true, encoding: 'UTF-8') // 后续处理输出 spectralOutput = spectralOutput.replace('\n', '<br>') if (!spectralOutput.contains('0 errors')) { echo spectralOutput currentBuild.result = 'FAILED' } echo spectralOutput
这种方式无需捕获异常,直接获取全部输出后,根据内容自行判断设置构建状态。
方法2:用returnStatus+输出重定向到临时文件
由于returnStatus和returnStdout无法同时启用,可将脚本输出重定向到临时文件,读取文件内容的同时用returnStatus获取退出码:
def tempFile = "${WORKSPACE}\\spectral_output.txt" int exitCode = bat(script: ''' @spectral lint \"%WORKSPACE%\\\\SelfContained\\\\*.json\" --ruleset \"%WORKSPACE%\\\\spectral\\\\.spectral.json\" > ''' + tempFile + ''' 2>&1 ''', returnStatus: true) String spectralOutput = readFile(file: tempFile, encoding: 'UTF-8') // 清理临时文件 bat(script: "del ${tempFile}") // 处理输出与构建状态 spectralOutput = spectralOutput.replace('\n', '<br>') if (exitCode != 0 || !spectralOutput.contains('0 errors')) { echo spectralOutput currentBuild.result = 'FAILED' } echo spectralOutput
其中2>&1用于将标准错误输出也重定向到文件,确保捕获所有输出内容。
方法3:从异常中提取输出(兼容性有限)
部分场景下,hudson.AbortException的异常信息会包含脚本输出,可尝试从中提取:
String spectralOutput try { spectralOutput = bat(script: ''' @spectral lint \"%WORKSPACE%\\\\SelfContained\\\\*.json\" --ruleset \"%WORKSPACE%\\\\spectral\\\\.spectral.json\" ''', returnStdout: true, encoding: 'UTF-8') } catch (hudson.AbortException e) { // 提取异常中的输出内容,需根据实际环境调整格式处理逻辑 spectralOutput = e.getMessage()?.replace('script returned exit code ', '') ?: '' spectralOutput = spectralOutput.replace('\n', '<br>') if (!spectralOutput.contains('0 errors')) { echo spectralOutput currentBuild.result = 'FAILED' } echo spectralOutput }
这种方式依赖异常信息的固定格式,兼容性不如前两种方法,仅作为备选。
内容的提问来源于stack exchange,提问作者Lieven Cardoen
相关产品推荐
相关产品推荐

