使用jq的--arg参数作为select过滤器无法生效如何解决
问题根源
核心问题出在shell变量的作用域:你在第二个命令开头定义的SERVICE_NAME=mysvc RELEASE_NAMESPACE=prod是仅作用于紧随其后的kubectl命令的环境变量,管道后面jq命令的参数中,${SERVICE_NAME}.${RELEASE_NAMESPACE}是由当前shell执行展开的,而当前shell中这两个变量没有赋值,最终你传给jq的SVC参数实际值为.(两个空变量拼接的结果),自然匹配不到mysvc.prod。
你尝试的错误写法问题说明
.canary == "$SVC":错误,jq中双引号包裹的内容是字符串字面量,这个规则会匹配canary字段值为$SVC(字面量)的条目,不会读取jq的SVC变量值.canary == "$SERVICE_NAME.$RELEASE_NAMESPACE":错误,jq默认不会直接读取shell的环境变量,除非你使用jq 1.6及以上版本的env内置变量(同时需要将shell变量导出为环境变量),否则这个写法也是匹配字面量字符串。
验证方法
你可以先把jq过滤器临时改为[$SVC]执行,就能看到传入的SVC值实际是.而非你期望的mysvc.prod,即可确认问题根源。
正确写法
先将变量赋值到当前shell,再执行后续命令即可,示例如下:
# 先在当前shell定义变量,后续所有命令都能读取到 TS_SEC_START=1534574204 SERVICE_NAME=mysvc RELEASE_NAMESPACE=prod kubectl -n istio-system logs deployment/flagger --tail=50 | grep '^{' | \ jq --arg TS_SEC_START "$TS_SEC_START" --arg SVC "${SERVICE_NAME}.${RELEASE_NAMESPACE}" \ -s 'map(select(.ts | (split(".")[0] + "Z") | fromdateiso8601 > ($TS_SEC_START | tonumber)) | select(.canary == $SVC))'
如果不想变量残留在当前shell环境,可以用子shell包裹:
( TS_SEC_START=1534574204 SERVICE_NAME=mysvc RELEASE_NAMESPACE=prod kubectl -n istio-system logs deployment/flagger --tail=50 | grep '^{' | \ jq --arg TS_SEC_START "$TS_SEC_START" --arg SVC "${SERVICE_NAME}.${RELEASE_NAMESPACE}" \ -s 'map(select(.ts | (split(".")[0] + "Z") | fromdateiso8601 > ($TS_SEC_START | tonumber)) | select(.canary == $SVC))' )
内容的提问来源于stack exchange,提问作者turbonerd
相关产品推荐
相关产品推荐

