"Unexpected $end" 使用 bash 变量时
"Unexpected $end" when using bash variables
我有一个相当简单的 bash 脚本,我想根据环境变量的值启用或禁用 jq 过滤器。
这是脚本的简化版本:
JSON='{ "key1": { "name":"foo" }, "key2": { "name":"bar" } }'
OPTIONAL_FILTER=""
if [[ "$FLAG" == "value" ]]; then
OPTIONAL_FILTER='| select(.key == "key2")'
fi
jq 'to_entries[] '${OPTIONAL_FILTER}' | .value.name' <<< $JSON
当我 运行 使用 FLAG=""
的脚本时,一切都按预期工作,我得到输出:
"foo"
"bar"
但是如果我设置FLAG="value"
,然后我得到以下错误:
jq: error: syntax error, unexpected $end (Unix shell quoting issues?) at <top-level>, line 1:
to_entries[] |
jq: 1 compile error
当我 运行 在 zsh 中执行相同的命令时,我没有收到此错误,我得到的只是 "foo"
的预期输出
我在 shell 脚本方面不是很有经验。我猜我的字符串中插入了一个空字符或其他类似的输入终止符,但我无法确认这一点或找到一个好的替代方法。它特别令人烦恼,因为它似乎是 shell-特定的。我用于大部分测试的 zsh 可以很好地处理代码。当我尝试 运行 一个我看到错误的 .sh
脚本时,我只会收到该错误。
最终目标是使可选过滤器正常工作。如果我错过了一个特定于 jq 的选项,我愿意接受其他选择。我尝试使用 jq 'to_entries[] $ENV.OPTIONAL_FILTER | .value.name' <<< $JSON
,但得到 jq: error: syntax error, unexpected '$', expecting $end
> bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
您插入 ${OPTIONAL_FILTER}
的方式导致它被分成多个单词,这意味着 jq
收到的参数比预期的多。 Bash 解释命令就像你写的一样:
jq 'to_entries[] |' 'select(.key' '==' '"key2")' '| .value.name' <<< $JSON
您可以引用它以确保它是一个单词:
jq 'to_entries[] '"${OPTIONAL_FILTER}"' | .value.name' <<< $JSON
或者在整个过程中使用双引号,这样您就不必跳入跳出单引号:
jq "to_entries[] ${OPTIONAL_FILTER} | .value.name" <<< $JSON
有关详细信息,请参阅:
如果可能,几乎总是最好避免通过字符串插值来操纵程序文本;幸运的是,据我所知,使用 jq 不仅可行而且非常简单。
在当前情况下,您可以使用 --arg command-line 选项,如下所示:
jq --arg flag "$FLAG" '
to_entries[]
| if $flag == "value" then select(.key == "key2")
else . end
| .value.name' <<< $JSON
我有一个相当简单的 bash 脚本,我想根据环境变量的值启用或禁用 jq 过滤器。
这是脚本的简化版本:
JSON='{ "key1": { "name":"foo" }, "key2": { "name":"bar" } }'
OPTIONAL_FILTER=""
if [[ "$FLAG" == "value" ]]; then
OPTIONAL_FILTER='| select(.key == "key2")'
fi
jq 'to_entries[] '${OPTIONAL_FILTER}' | .value.name' <<< $JSON
当我 运行 使用 FLAG=""
的脚本时,一切都按预期工作,我得到输出:
"foo"
"bar"
但是如果我设置FLAG="value"
,然后我得到以下错误:
jq: error: syntax error, unexpected $end (Unix shell quoting issues?) at <top-level>, line 1:
to_entries[] |
jq: 1 compile error
当我 运行 在 zsh 中执行相同的命令时,我没有收到此错误,我得到的只是 "foo"
我在 shell 脚本方面不是很有经验。我猜我的字符串中插入了一个空字符或其他类似的输入终止符,但我无法确认这一点或找到一个好的替代方法。它特别令人烦恼,因为它似乎是 shell-特定的。我用于大部分测试的 zsh 可以很好地处理代码。当我尝试 运行 一个我看到错误的 .sh
脚本时,我只会收到该错误。
最终目标是使可选过滤器正常工作。如果我错过了一个特定于 jq 的选项,我愿意接受其他选择。我尝试使用 jq 'to_entries[] $ENV.OPTIONAL_FILTER | .value.name' <<< $JSON
,但得到 jq: error: syntax error, unexpected '$', expecting $end
> bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
您插入 ${OPTIONAL_FILTER}
的方式导致它被分成多个单词,这意味着 jq
收到的参数比预期的多。 Bash 解释命令就像你写的一样:
jq 'to_entries[] |' 'select(.key' '==' '"key2")' '| .value.name' <<< $JSON
您可以引用它以确保它是一个单词:
jq 'to_entries[] '"${OPTIONAL_FILTER}"' | .value.name' <<< $JSON
或者在整个过程中使用双引号,这样您就不必跳入跳出单引号:
jq "to_entries[] ${OPTIONAL_FILTER} | .value.name" <<< $JSON
有关详细信息,请参阅:
如果可能,几乎总是最好避免通过字符串插值来操纵程序文本;幸运的是,据我所知,使用 jq 不仅可行而且非常简单。
在当前情况下,您可以使用 --arg command-line 选项,如下所示:
jq --arg flag "$FLAG" '
to_entries[]
| if $flag == "value" then select(.key == "key2")
else . end
| .value.name' <<< $JSON