ShellCheck se queja de que mi expresión no esté entre comillas dobles cuando realmente lo está; ¿por qué?

ShellCheck se queja de que mi expresión no esté entre comillas dobles cuando realmente lo está; ¿por qué?

Estoy escribiendo un script bash con la CLI de AWS y shellcheckobtengo un error que creo que es incorrecto. Me gustaría intentar descubrir por qué se queja.

Aquí está el código y el mensaje de error:

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.

No puedo hacer que el código se alinee correctamente en el editor SO, pero ^--apunta al *código. Esta parte:

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

El error proporcionaun enlace a la documentación de ShellCheckcomo referencia, pero cuando vuelvo a verificar todo, parece que estoy cumpliendo. :D

Supongo que está *arruinando las cosas y sé que puedo solucionar esto haciéndolo, shellcheck -e SC2016pero realmente me pregunto qué podría estar causando que Shellcheck carpe.

¿Algunas ideas?

Respuesta1

Es un falso positivo, pero no es lo que crees. No tiene nada que ver con *y no me señaló allí. Le molesta `Name`estar entre comillas simples. Por ejemplo, echo '`Name`'produce la misma advertencia, porque cree que desea que se evalúen las comillas invertidas, por lo que le advierte que no lo serán.

Respuesta2

No es una respuesta, sino un comentario formateado:

De manera pedante, no deberías usar un forbucle, sino un while readbucle:

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
)

forbucles leídos separados por espacios en blancopalabras, whilebucles leídoslíneas-- verhttp://mywiki.wooledge.org/BashFAQ/001

Alternativamente, use readarraypara capturar la salida

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 largos e ilegibles, almacenar las opciones en una matriz puede mejorar la legibilidad:

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

información relacionada