如何在Jenkinsfile中使用jq捕获curl响应以准确判断构建执行成败
问题根因
- 当前Pipeline的
sh步骤默认以shell命令的退出码作为执行成功的唯一判定标准 - 原有curl命令仅完成网络层请求调用,只要没有出现网络超时、连接中断这类传输层错误,哪怕接口返回的JSON里
status字段不是success,curl的退出码依然是0,自然会触发Jenkins的success判定,跳过failure分支的通知逻辑
改造实现方案
整体逻辑不需要改动你原有post块的Slack通知配置,只需要替换steps块里的shell脚本,通过临时文件存储接口响应、校验curl执行状态、用jq解析JSON字段,校验不通过时主动抛出非0退出码让Jenkins自动走失败流程即可。
前置要求:所有运行该Pipeline的Jenkins Agent节点需提前安装jq工具,否则脚本会因缺少命令执行失败
改造后的steps块代码如下:
steps { sh ''' #!/bin/bash set +e # 创建临时文件存储接口响应 RESP_TMP=$(mktemp) # 执行curl请求,同时记录curl本身的执行结果 curl -d "{ \"ref\": \"${BRANCH_NAME}\" }" \ -H "Accept: application/json" \ '#somelink/api' \ -k -q \ --silent --show-error \ -o "$RESP_TMP" CURL_RC=$? set -e # 校验1:curl本身是否执行失败(如网络不通、SSL校验报错等) if [ $CURL_RC -ne 0 ]; then echo "curl请求执行失败,错误码:$CURL_RC" rm -f "$RESP_TMP" exit 1 fi # 校验2:解析接口返回的JSON内容,提取status字段 API_STATUS=$(jq -r '.status // empty' "$RESP_TMP" 2>/dev/null) if [ -z "$API_STATUS" ]; then echo "接口返回内容无法解析为合法JSON,原始响应如下:" cat "$RESP_TMP" rm -f "$RESP_TMP" exit 1 fi # 校验3:判断status字段是否为预期的success值 if [ "$API_STATUS" != "success" ]; then echo "接口业务调用失败,返回status值:$API_STATUS,原始响应如下:" cat "$RESP_TMP" rm -f "$RESP_TMP" exit 1 fi # 所有校验通过,清理临时文件 echo "接口调用校验通过,返回status:$API_STATUS" rm -f "$RESP_TMP" ''' }
方案说明
- 所有校验环节触发失败时,脚本会返回非0退出码,Jenkins会自动将构建标记为失败,完全复用你原有的
post块中的Slack通知逻辑,不需要额外改动通知配置 - 异常场景下会将原始接口响应直接打印到Jenkins控制台,排查问题时不需要额外抓取网络请求内容
- 脚本会自动清理临时文件,不会在Agent节点残留无用文件
- 过滤了curl默认输出的无意义传输进度日志,控制台输出更聚焦有效信息
内容的提问来源于stack exchange,提问作者Gifter Villanueva
相关产品推荐
相关产品推荐

