![ShellCheck придирается, что мое выражение не заключено в двойные кавычки, хотя на самом деле оно там находится. Почему?](https://rvso.com/image/169441/ShellCheck%20%D0%BF%D1%80%D0%B8%D0%B4%D0%B8%D1%80%D0%B0%D0%B5%D1%82%D1%81%D1%8F%2C%20%D1%87%D1%82%D0%BE%20%D0%BC%D0%BE%D0%B5%20%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%BD%D0%B5%20%D0%B7%D0%B0%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%BE%20%D0%B2%20%D0%B4%D0%B2%D0%BE%D0%B9%D0%BD%D1%8B%D0%B5%20%D0%BA%D0%B0%D0%B2%D1%8B%D1%87%D0%BA%D0%B8%2C%20%D1%85%D0%BE%D1%82%D1%8F%20%D0%BD%D0%B0%20%D1%81%D0%B0%D0%BC%D0%BE%D0%BC%20%D0%B4%D0%B5%D0%BB%D0%B5%20%D0%BE%D0%BD%D0%BE%20%D1%82%D0%B0%D0%BC%20%D0%BD%D0%B0%D1%85%D0%BE%D0%B4%D0%B8%D1%82%D1%81%D1%8F.%20%D0%9F%D0%BE%D1%87%D0%B5%D0%BC%D1%83%3F.png)
Я пишу скрипт bash с помощью AWS CLI и 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[@]}")