我正在使用 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[@]}")