![ShellCheck は、実際には二重引用符で囲まれているのに、式が二重引用符で囲まれていないと文句を言います。なぜでしょうか?](https://rvso.com/image/169441/ShellCheck%20%E3%81%AF%E3%80%81%E5%AE%9F%E9%9A%9B%E3%81%AB%E3%81%AF%E4%BA%8C%E9%87%8D%E5%BC%95%E7%94%A8%E7%AC%A6%E3%81%A7%E5%9B%B2%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%AB%E3%80%81%E5%BC%8F%E3%81%8C%E4%BA%8C%E9%87%8D%E5%BC%95%E7%94%A8%E7%AC%A6%E3%81%A7%E5%9B%B2%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%81%A8%E6%96%87%E5%8F%A5%E3%82%92%E8%A8%80%E3%81%84%E3%81%BE%E3%81%99%E3%80%82%E3%81%AA%E3%81%9C%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%81%8B%3F.png)
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 が carp する原因が何なのか本当に疑問に思っています。
何か案は?
答え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[@]}")