You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkins Groovy Pipeline捕获Python脚本退出输出问题求助

问题

在Jenkins流水线的某个阶段中,我用try-catch执行Python脚本。脚本会根据输入参数,要么正常输出成功结果,要么打印失败信息后用exit()终止。我需要区分脚本是成功执行还是因exit()终止,同时获取两种场景下的打印内容。目前脚本正常执行时能拿到输出,但脚本通过exit()终止时,Jenkins能捕获异常,却拿不到脚本之前打印的内容。

相关代码如下:

Jenkinsfile 阶段代码

stage('Test branch') {
            steps {
                script {
                    test_results = 'position 1'
                    try {
                        test_results = sh (
                            script: "python3 \${WORKSPACE}/testingjenkinsexit.py notpass",
                            returnStdout: true
                        ).trim()
                        echo "Test results in passed test: ${test_results}"
                    } catch (err) {
                        echo "Test results in failed test numb 1: " + test_results
                        echo "Test results in failed test numb 2: ${test_results}"
                        echo err.getMessage()
                        println err.dump()
                    }
                }
            }
        }

Python 脚本代码

from sys        import argv

def testingjenkins(desired_output):

    #print relevant test results. If at least one test failed, stop execution
    if desired_output == "'pass'":
        print(desired_output)
    else:
        print('tests did not pass')
        exit('Deployement interrupted by python.')

desired_output = "'" + str(argv[1]) + "'"

if __name__ == "__main__":

    testingjenkins(desired_output)

原因分析

  1. sh步骤的返回逻辑限制:当使用returnStdout: true时,仅当命令以返回码0正常退出时,才会将标准输出赋值给变量。如果命令以非0返回码退出(比如Python的exit()),sh步骤会直接抛出异常,此时标准输出不会被写入test_results,变量仍保留初始值position 1。
  2. 输出流差异:Python的exit()传入的消息会输出到标准错误流(stderr),而非标准输出流(stdout),这部分内容被包含在Jenkins捕获的异常中,但你没有正确提取。

解决方案

最优方案:修改Jenkinssh步骤配置,完整捕获输出与状态

使用sh步骤的returnStdout、returnStderr和returnStatus参数,同时捕获标准输出、错误输出和命令退出码,避免直接抛出异常,完全控制结果处理逻辑:

修改后的Jenkinsfile代码:

stage('Test branch') {
    steps {
        script {
            def shResult = sh (
                script: "python3 \${WORKSPACE}/testingjenkinsexit.py notpass",
                returnStdout: true,
                returnStderr: true,
                returnStatus: true
            )
            
            def stdoutContent = shResult.stdout.trim()
            def stderrContent = shResult.stderr.trim()
            def exitCode = shResult.returnStatus
            
            if (exitCode == 0) {
                echo "测试通过,结果:${stdoutContent}"
            } else {
                echo "测试失败,标准输出内容:${stdoutContent}"
                echo "测试失败,错误输出内容:${stderrContent}"
            }
        }
    }
}

可选方案:调整Python脚本输出行为

如果希望将退出消息输出到stdout,可以修改Python脚本,先打印退出消息再调用exit():

else:
    print('tests did not pass')
    print('Deployement interrupted by python.')
    exit()

但更推荐第一种方案,无需修改脚本逻辑,直接在Jenkins层面完成所有信息的捕获与判断。


内容的提问来源于stack exchange,提问作者EmJReg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:45:32