JQ select命令行运行正常 置于bash脚本中执行失效如何解决
问题原因
- NAME变量携带不可见字符:脚本中通过其他命令获取的
NAME变量大概率末尾带了换行符、回车符或者多余空格,手动在命令行测试时输入的是纯文本NAME值,没有这些不可见字符,所以能正常匹配,脚本中匹配失败返回null。 - curl输出包含无关内容:默认curl会输出进度条、状态提示等内容,部分环境下这类非JSON内容会混入标准输出,导致jq解析失败。
- JSON结构不匹配遍历规则:当前jq表达式用了
.[]遍历数组,如果脚本执行环境和手动执行环境存在差异(比如请求参数、权限差异)导致API返回单个JSON对象而非数组,.[]会直接遍历对象的属性值而非对象本身,无法匹配到.name字段。
解决方法
- 清理NAME变量的不可见字符,获取NAME时去掉换行、回车符:
NAME=$(其他命令 | tr -d '\n\r')
- 给curl添加
-s静默参数,关闭无关输出,避免污染JSON结构:
# -s参数会关闭curl的进度条、状态提示等非业务输出 RESP=$(curl -s --header "PRIVATE-TOKEN:<token>" "<api_endpoint>")
- 修改jq表达式,兼容数组和单个对象两种返回结构,同时增加空值兜底:
ID=$(echo "$RESP" | jq -r --arg NAMES "$NAME" '(if type == "array" then .[] else . end) | select(.name == $NAMES) | .id // empty')
修正后完整代码示例
NAME=$(output of another command which will be the same as that of the name value in the JSON above | tr -d '\n\r') ID=$(curl -s --header "PRIVATE-TOKEN:<token>" "<api_endpoint>" | jq -r --arg NAMES "$NAME" '(if type == "array" then .[] else . end) | select(.name==$NAMES) | .id // empty') echo ID="$ID"
内容的提问来源于stack exchange,提问作者Sharath Prakash
相关产品推荐
相关产品推荐

