web-dev-qa-db-ja.com

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を実行することでこれを回避できることを知っていますが、何がシェルチェックに鯉を引き起こしているのかと本当に思っています。

何か案は?

9
Michael J

これは誤検知ですが、あなたが思っているものではありません。それは*とは関係なく、私のためにそこを指し示しませんでした。 `Name`が一重引用符で囲まれていることに腹を立てています。たとえば、echo '`Name`'は同じ警告を生成します。これは、バッククォートを評価する必要があると考えているため、バッククォートが評価されないことを警告しています。

答えではなく、フォーマットされたコメント:

厳密には、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 loops read whitespace-separatedwordswhile loops readlines-参照 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[@]}")
3
glenn jackman