Jenkins Pipeline 中当命令执行错误时,Jenkin 目前还不能直接支持返回标准错误信息。本文讨论一种返回标准错误的方法。 举例 以一个简单的命令: ls 为例,说明 sh 的用法。 假设使用如下的 pipeline 文件,其中仅包含 ls / 命令 pipeline{ agent any stages{ stage('sh输出'){ steps{ script{ out = sh( label: 'listing directory', returnStdout: true, script: "ls /" ) } } } } } 正常情况 StdOut 上面这段 Pipeline 定义文件里,重点是中间5行: out = sh( label: 'listing directory', returnStdout: true, script: "ls /" ) 这段话将运行 script 指定的命令,也就是 ls / 的标准输出 StdOut 赋值给 out 变量。正常情况下,得到的是类似下面的: bin boot dev etc home initrd.img lib lib64 lost+found media mnt .... 异常情况 StdErr 如果命令执行过程出现错误,比如实际执行的命令是针对不存在的路径,比如 out = sh( label: 'listing directory', returnStdout: true, script: "ls /notExist" ) 这个命令将在标准错误 StdErr 输出下面的信息: ls: cannot access /notExist: No such file or directory 然而标准输出 StdOut 则为空。那么上面这种 Pipeline 写法有两个问题: 不能返回执行命令的标准错误信息,只能返回 StdOut 内容,异常情况下为空 不能抛错,使当前和后续 stage 停止,也不能中断整个任务,更不能将整个任务的状态标记为 Failure 下面介绍解决方案,以解决上面两个问题。 解决方法 目前的 Jenkins 版本,不提供输出标准错误 StdErr 的方法,不过可以通过下面的做法绕过: 标准错误合并输出到标准输出,再输出到文件 判断运行状态 returnStatus 具体是下面的写法: pipeline{ agent any stages{ stage('sh输出'){ steps{ script{ status = sh( label: 'listing directory', // 返回运行状态 returnStatus: true, // 合并标准错误 StdErr 到文件和标准输出 StdOut script: "ls /ff \>test.log 2>&1" ) // 从文件读出标准错误 StdErr 信息 out = readFile(file: "test.log") if (status != 0) { // 使当前 stage 运行失败,同时输出错误信息。 error('TEST FAILED.') } } } } } } 这里面关键的一步 error() 的用法,见Declarative Pipeline 语法简介。执行了上面的语句之后,整个任务以失败结束: 同时后续的 Stage 都不再执行,从控制台日志里能看到: Stage skipped due to earlier failure(s) 注意:上面合并标准错误的命令里,两次重定向的顺序不能颠倒,必须先导出到文件 >test.log ,再处理标准错误 2>&1 (全文完)