Bash脚本中jq无法解析$1变量导致old_nodes为空的问题
问题排查与解决
1. 变量old_nodes赋值为空的核心原因
最可能是两个细节出错:
- 引号使用错误导致参数未解析:如果
cmdcopy用单引号定义,单引号内的$1不会被Bash替换成脚本传入的参数,会被当成字符串字面量传给jq,自然筛选不到匹配节点。比如你写:
这里的cmdcopy='kubectl get nodes -o json | jq -r ".items[] | select(.status.nodeInfo.osImage | contains(\"$1\")) | .metadata.name"'$1就是字符串"$1",不是你实际要筛选的镜像名,所以结果为空。而你直接执行命令时应该手动替换了$1,所以能得到正确结果。 - 未用命令替换执行命令:如果赋值时直接写
old_nodes=$cmdcopy,这只是把命令文本赋值给变量,并没有执行命令,结果自然不是节点列表。
对应解决办法:
- 直接跳过
cmdcopy变量,用命令替换直接获取结果(最稳妥):old_nodes=$(kubectl get nodes -o json | jq -r ".items[] | select(.status.nodeInfo.osImage | contains(\"$1\")) | .metadata.name") - 一定要用
cmdcopy的话,改成双引号定义并转义jq内的引号,再用eval执行:cmdcopy="kubectl get nodes -o json | jq -r '.items[] | select(.status.nodeInfo.osImage | contains(\"$1\")) | .metadata.name'" old_nodes=$(eval "$cmdcopy")
2. 循环变量拼写错误的问题
你把循环里的old_nodes写成了old_node,比如:
for node in $old_node; do # 操作逻辑 done
old_node是未定义的空变量,循环根本不会执行有效内容。只要把变量名改成old_nodes即可:
for node in $old_nodes; do # 你的操作逻辑 done
如果节点名称可能包含空格(K8s节点名一般不会,但防患未然),推荐用数组存储再遍历:
readarray -t old_nodes < <(kubectl get nodes -o json | jq -r ".items[] | select(.status.nodeInfo.osImage | contains(\"$1\")) | .metadata.name") for node in "${old_nodes[@]}"; do echo "处理节点:$node" done
内容的提问来源于stack exchange,提问作者Djoby
相关产品推荐
相关产品推荐

