ShellCheck 抱怨我的表达式没有用双引号引起来,而实际上它是用双引号引起来的;为什么?

ShellCheck 抱怨我的表达式没有用双引号引起来,而实际上它是用双引号引起来的;为什么?

我正在使用 AWS CLI 编写 bash 脚本,但shellcheck给出了一个我认为不正确的错误。我想尝试弄清楚为什么它会吹毛求疵。

这是代码和错误消息:

for server in $(${aws} ec2 describe-instances --query 'Reservations[].Instances[][].{Name: Tags[?Key==`Name`].Value[] | [0]}' --filters "Name=tag:Name,Values=${server_name}*" --output text);
                                                                                                                                                                            ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that.

我无法让代码在 SO 编辑器中正确排列,但它^--指向*代码中的 。这部分:

"Name=tag:Name,Values=${server_name}*"

该错误提供了ShellCheck 文档的链接供参考,但当我仔细检查所有内容时,看起来我是合规的。 :D

我猜这是*把事情搞砸了,我知道我可以通过这样做来解决这个问题,shellcheck -e SC2016但我真的想知道是什么可能导致 shellcheck 鲤鱼。

有任何想法吗?

答案1

这是一种误报,但它并不是您想象的那样。它与 无关*,并且没有向我指出那里。它对`Name`单引号内的内容感到不安。例如,echo '`Name`'会产生相同的警告,因为它认为您希望对反引号进行计算,因此它警告您不会进行计算。

答案2

不是答案,而是格式化的评论:

迂腐地,你不应该使用循环for,而应该使用while read循环:

while IFS= read -r server; do
    : do stuff here
done < <(
    "$aws" ec2 describe-instances \
        --query 'Reservations[].Instances[][].{Name: Tags[?Key==`Name`].Value[] | [0]}' \
        --filters "Name=tag:Name,Values=${server_name}*" \
        --output text
)

for循环读取空格分隔,while循环读取线- 看http://mywiki.wooledge.org/BashFAQ/001

或者,使用readarray捕获输出

readaray -t servers < <(
    "$aws" ec2 describe-instances \
        --query 'Reservations[].Instances[][].{Name: Tags[?Key==`Name`].Value[] | [0]}' \
        --filters "Name=tag:Name,Values=${server_name}*" \
        --output text
)

for server in "${servers}"; do ...; done

最后,对于长且不可读的命令,将选项存储在数组中可以提高可读性:

opts=(
    --query 'Reservations[].Instances[][].{Name: Tags[?Key==`Name`].Value[] | [0]}' 
    --filters "Name=tag:Name,Values=${server_name}*"
    --output text
)

readarray -t servers < <("$aws" ec2 describe-instances "${opts[@]}")

相关内容