我正在努力了解以下错误的原因以及如何解决它。
我有这段代码:
set_filters() {
json=$1
filters='"Name=instance-state-name,Values=running,stopped"'
echo $json | jq -r '. | keys[]' | \
while read tag ; do
value=$(echo "$json" | jq -r ".[\"$tag\"]")
filters="$filters \"Name=tag:${tag},Values=${value}\""
done
echo $filters
}
set_filters '{"Name": "*FOO*", "Cost Center": "XX111"}'
我期待的输出:
"Name=instance-state-name,Values=running,stopped" "Name=tag:Cost Center,Values=XX111" "Name=tag:Name,Values=*FOO*"
我得到的输出:
"Name=instance-state-name,Values=running,stopped"
如果我插入echo语句以帮助调试:
set_filters() {
json=$1
filters='"Name=instance-state-name,Values=running,stopped"'
echo $json | jq -r '. | keys[]' | \
while read tag ; do
value=$(echo "$json" | jq -r ".[\"$tag\"]")
filters="$filters \"Name=tag:${tag},Values=${value}\""
echo "FILTERS INSIDE LOOP: $filters"
done
echo "FILTERS OUTSIDE LOOP: $filters"
}
我得到的输出是:
FILTERS INSIDE LOOP: "Name=instance-state-name,Values=running,stopped" "Name=tag:Cost Center,Values=XX111"
FILTERS INSIDE LOOP: "Name=instance-state-name,Values=running,stopped" "Name=tag:Cost Center,Values=XX111" "Name=tag:Name,Values=*FOO*"
FILTERS OUTSIDE LOOP: "Name=instance-state-name,Values=running,stopped"
我无法解释这种行为。在Bash以外的语言中,我会假设变量$filters
的变量范围问题,但我认为范围基本上是全局的。
我在Red Hat Enterprise Linux 6.8上使用JQ版本1.3和Bash版本4.1.2。
答案 0 :(得分:2)
Bash在子shell中执行循环,如果它们是管道的一部分。例如,请参阅BashFAQ/024和" Bash Script: While-Loop Subshell Dilemma"。
可能的解决方法是使用流程替换:
while read tag; do
...
done < <(jq -r '. | keys[]' <<< "$1")