Как проверить стандартный вывод команды в Bash при проверке условий? - PullRequest
0 голосов
/ 25 октября 2019

Я пытаюсь проверить вывод команды как условие прорыва для цикла while в Bash, но он продолжает пропускать блок, даже когда последний эхо подтверждает значение как "DELETE_IN_PROGRESS".

Вот что у меня есть:

stackname=cf_test
while [[ $(aws cloudformation describe-stacks --stack-name ${stackname} | jq '.Stacks | .[0] | .StackStatus') == "DELETE_IN_PROGRESS" ]]; do
  echo -e "   $(aws cloudformation describe-stacks --stack-name ${stackname} | jq '.Stacks | .[0] | .StackStatus'): waiting for current stack to delete before re-deploying..."
  sleep 30
done

echo -e $(aws cloudformation describe-stacks --stack-name ${stackname} | jq '.Stacks | .[0] | .StackStatus')

Что я должен изменить?

edit:

Добавление -x флаг отладки, дает:

▶ bash -x ~/Downloads/test_script.sh
+ stackname=cf_test
++ aws cloudformation describe-stacks --stack-name cf_test
++ jq '.Stacks | .[0] | .StackStatus'
+ [[ "DELETE_IN_PROGRESS" == \D\E\L\E\T\E\_\I\N\_\P\R\O\G\R\E\S\S ]]
++ aws cloudformation describe-stacks --stack-name cf_test
++ jq '.Stacks | .[0] | .StackStatus'
+ echo -e '"DELETE_IN_PROGRESS"'
"DELETE_IN_PROGRESS"

Ответы [ 2 ]

2 голосов
/ 25 октября 2019

Я бы переместил сравнение внутрь jq. По умолчанию, jq будет успешным независимо от логического статуса сделанного вами сравнения.

% jq -n '3 == 3'; echo $?
true
0
% jq -n '3 != 3'; echo $?
false
0

Чтобы изменить это, используйте параметр -e.

% jq -en '3 == 3'; echo $?
true
0
% jq -en '3 != 3'; echo $?
false
1

Выполнениеэто устраняет необходимость в команде [[ ... ]].

while x=$(aws cloudformation describe-stacks --stack-name ${stackname});
      jq -ne --arg x "$x" '$x.Stacks.[0].StackStatus == "DELETE_IN_PROGRESS"'; do
  printf '%s: waiting for current stack to delete before re-deploying...\n' "$x"
  sleep 30
done

printf '%s\n' "$x"
1 голос
/ 26 октября 2019

Ваш журнал отладки показывает проблему (даже если сама строка [[ странно скрывает ее):

+ echo -e '"DELETE_IN_PROGRESS"'

Значение, которое вы сравниваете, содержит буквальные двойные кавычки. Вот почему матч провалился. Правая часть == содержит синтаксические двойные кавычки, которые не рассматриваются как часть строки.

Чтобы исправить это, используйте jq -r для вывода строки без JSON-форматирования и экранирования:

json='{ "foo": "bar" }'
jq '.foo' <<< "$json"     # Shows bad 5 character value: "bar"
jq -r '.foo' <<< "$json"  # Shows good 3 character value: bar

В вашем случае:

while [[ $(aws cloudformation describe-stacks --stack-name ${stackname} | jq -r '.Stacks | .[0] | .StackStatus') == "DELETE_IN_PROGRESS" ]]; doq -r '.Stacks | .[0] | .StackStatus') == "DELETE_IN_PROGRESS" ]]; do
  echo "Still deleting"
  sleep 30
done
...