ShellCheck beschwert sich, dass mein Ausdruck nicht in Anführungszeichen steht, obwohl er es wirklich ist. Warum?

ShellCheck beschwert sich, dass mein Ausdruck nicht in Anführungszeichen steht, obwohl er es wirklich ist. Warum?

Ich schreibe ein Bash-Skript mit der AWS CLI und shellcheckerhalte einen Fehler, der meiner Meinung nach falsch ist. Ich möchte versuchen, herauszufinden, warum es so nervt.

Hier ist der Code und die Fehlermeldung:

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.

Ich kann den Code im SO-Editor nicht richtig ausrichten, aber im Code ^--zeigt das auf das . Dieser Teil:*

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

Der Fehler liefertein Link zur ShellCheck-Dokumentationals Referenz, aber wenn ich alles doppelt überprüfe, sieht es so aus, als ob ich die Vorschriften einhalte. :D

Ich vermute, dass das die *Sache durcheinander bringt, und ich weiß, dass ich das umgehen kann, indem ich das tue shellcheck -e SC2016, aber ich frage mich wirklich, was die Ursache für das Problem mit Shellcheck sein könnte.

Irgendwelche Ideen?

Antwort1

Es ist ein falsch positives Ergebnis, aber nicht das, das Sie vermuten. Es hat nichts mit dem zu tun *und hat mich auch nicht dorthin geführt. Es ist verärgert, weil `Name`es in einfachen Anführungszeichen steht. Beispielsweise echo '`Name`'erzeugt dieselbe Warnung, weil es denkt, dass Sie möchten, dass die Backticks ausgewertet werden, und Sie deshalb warnt, dass dies nicht der Fall sein wird.

Antwort2

Keine Antwort, sondern ein formatierter Kommentar:

Um genau zu sein, sollten Sie keine Schleife verwenden for, sondern eine while readSchleife:

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
)

forSchleifen lesen durch Leerzeichen getrenntWörter, whileSchleifen lesenLinien-- sehenhttp://mywiki.wooledge.org/BashFAQ/001

Alternativ können Sie readarraydie Ausgabe mit erfassen

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

Und schließlich kann das Speichern der Optionen in einem Array bei langen und unlesbaren Befehlen die Lesbarkeit verbessern:

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

verwandte Informationen