ShellCheck está reclamando que minha expressão não está entre aspas duplas quando realmente está; por que?

ShellCheck está reclamando que minha expressão não está entre aspas duplas quando realmente está; por que?

Estou escrevendo um script bash com a AWS CLI e shellcheckestá apresentando um erro que considero incorreto. Eu gostaria de tentar descobrir por que está reclamando.

Aqui está o código e a mensagem de erro:

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.

Não consigo alinhar o código corretamente no editor SO, mas está ^--apontando para *no código. Esta parte:

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

O erro forneceum link para a documentação do ShellCheckpara referência, mas quando verifico tudo, parece que estou em conformidade. :D

Eu estou supondo que isso *está atrapalhando as coisas e sei que posso contornar isso fazendo isso, shellcheck -e SC2016mas estou realmente me perguntando o que pode estar causando o shellcheck nas carpas.

Alguma ideia?

Responder1

É um falso positivo, mas não é o que você pensa que é. Não tem nada a ver com *e não apontou para mim. Está chateado por `Name`estar entre aspas simples. Por exemplo, echo '`Name`'produz o mesmo aviso, porque pensa que você deseja que os crases sejam avaliados, então está avisando que não serão.

Responder2

Não é uma resposta, mas um comentário formatado:

Pedanticamente, você não deveria usar um forloop, mas um while readloop:

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
)

forloops lidos separados por espaços em brancopalavras, whileloops lidoslinhas-- verhttp://mywiki.wooledge.org/BashFAQ/001

Como alternativa, use readarraypara capturar a saída

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

Por último, para comandos longos e ilegíveis, armazenar as opções em um array pode melhorar a legibilidade:

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

informação relacionada