使用jq结合进程替换的Bash脚本变量更新失败及语法错误问题
问题解答
问题1:管道调用jq时变量domain_count无法更新
这是因为Bash中管道会创建子shell,while循环在子shell环境中执行,循环内对domain_count的修改仅作用于子shell,父shell的变量不会被同步更新,所以最终输出始终是初始值0。
解决办法
可以通过以下方式避免子shell限制:
- 启用
lastpipe选项(Bash 4.2及以上版本支持),让管道最后一个命令在当前shell执行:
shopt -s lastpipe domain_count=0 jq -r .domains[] variables.json | while read domain; do host="0.0.0.0 ${domain}" echo "$host" ((domain_count++)) done echo "$domain_count"
- 用大括号将循环包裹,结合进程替换保持上下文一致:
domain_count=0 { while read domain; do host="0.0.0.0 ${domain}" echo "$host" ((domain_count++)) done } < <(jq -r .domains[] variables.json) echo "$domain_count"
问题2:进程替换写法出现语法错误
这个错误是因为进程替换< <(...)是Bash独有的语法,如果脚本通过sh运行(比如脚本开头shebang为#!/bin/sh,或执行命令为sh generate.sh),就会触发语法错误——POSIX标准的sh不支持该特性。
解决办法
- 确保脚本开头的shebang指定Bash:
#!/bin/bash domain_count=0 while read domain do host="0.0.0.0 ${domain}" echo "$host" ((domain_count++)) done < <(jq -r .domains[] variables.json) echo "$domain_count"
- 若无法修改shebang,直接用Bash执行脚本:
bash generate.sh
另外建议给变量引用添加双引号(如echo "$host"),避免域名包含特殊字符时出现解析异常。
内容的提问来源于stack exchange,提问作者dsjfhdjshfjkdshjf
相关产品推荐
相关产品推荐

