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[@]}")

相關內容