如何用jq检查JSON中threatLevel是否≥GitLab CI/CD变量值?
用jq检查JSON中威胁等级阈值的Shell脚本解决方案
我有一个名为results.json的文件,内容结构如下:
{ "applicationId" : "application", "scanId" : "scanId", "policyEvaluationResult" : { "alerts" : [ { "trigger" : { "policyId" : "pid1", "policyName" : "Security-High", "threatLevel" : 9, "policyViolationId" : "pvid1" }, "trigger" : { "policyId" : "pid2", "policyName" : "Security-Low", "threatLevel" : 1, "policyViolationId" : "pvid2" } // 更多trigger对象... }] } }
需求很明确:编写bash/shell脚本,用jq工具检查这个文件,判断是否存在任意trigger对象的threatLevel大于等于GitLab CI/CD变量THRESHOLD_VALUE的值。如果存在,输出失败信息并返回退出码1;否则输出成功信息并返回退出码0。
我之前写了一段伪代码,想确认思路是否正确:
if (jq 'any(.threatLevel | contains (>=${THRESHOLD_VALUE}))') results.json; then echo 'failing pipeline' exit 1 else echo 'passing pipeline' exit 0 fi
伪代码的问题
思路方向是对的,但jq语法存在几个错误:
- 没有正确定位到
trigger对象的路径,需要从policyEvaluationResult.alerts数组中遍历每个元素的trigger contains函数不适合做数值比较,直接用>=即可any函数的用法需要调整,要指定遍历的目标集合
正确的脚本实现
#!/bin/bash # 先检查阈值变量是否已定义 if [ -z "${THRESHOLD_VALUE}" ]; then echo "错误:未定义THRESHOLD_VALUE变量" exit 1 fi # 使用jq执行检查逻辑,屏蔽输出只看退出码 if jq --arg threshold "${THRESHOLD_VALUE}" ' .policyEvaluationResult.alerts[] | .trigger | any(.threatLevel >= ($threshold | tonumber)) ' results.json > /dev/null; then echo "流水线失败:存在威胁等级≥${THRESHOLD_VALUE}的告警" exit 1 else echo "流水线通过:所有告警威胁等级均低于${THRESHOLD_VALUE}" exit 0 fi
关键细节说明
--arg threshold "${THRESHOLD_VALUE}":将Shell变量安全传入jq,避免直接字符串拼接引发的语法问题.policyEvaluationResult.alerts[]:遍历alerts数组中的每一个元素.trigger:提取每个alert对象里的trigger子对象any(.threatLevel >= ($threshold | tonumber)):判断是否存在任意一个trigger的threatLevel数值大于等于阈值(tonumber把传入的字符串阈值转为数值,避免字符串比较的误差)> /dev/null:屏蔽jq的输出内容,只利用它的退出码(返回true时退出码为0,false时为1)来控制脚本逻辑
内容的提问来源于stack exchange,提问作者cien
相关产品推荐
相关产品推荐

