Не удалось заставить работать условие IF в командах командной строки AWS в Jenkins

#linux #bash #amazon-web-services #jenkins #aws-cli

Вопрос:

Я пытаюсь запустить серию команд для aws через задание Дженкинса, но всякий раз, когда дело доходит до условия if, оно выдает ошибку

Вот список команд

 echo '****** Updating ASG ********'
aws autoscaling update-auto-scaling-group --auto-scaling-group-name test-asg --desired-capacity 2 --min-size 2 --max-size 6
sleep 200
echo '****** Initiating Instance Refresh ********'
aws autoscaling start-instance-refresh --auto-scaling-group-name test-asg --preferences '{"InstanceWarmup": 300, "MinHealthyPercentage": 100}'
while true;
do
    instance_refresh_status=$(aws autoscaling describe-instance-refreshes --auto-scaling-group-name test-asg --query "InstanceRefreshes[0].Status" --output text --region us-east-1)
    if (( "$instance_refresh_status" == "Successful" )); then
        break
    fi
    sleep 10
done

echo '****** Finished Instance Refresh ********'

echo '****** Updating ASG back to normal ********'
aws autoscaling update-auto-scaling-group --auto-scaling-group-name test-asg --desired-capacity 1 --min-size 1


 

Ошибка, которую я получаю, заключается в следующем в выводе Дженкинса

   instance_refresh_status=InProgress
  InProgress == Successful
/tmp/jenkins8251579523029552853.sh: 10: /tmp/jenkins8251579523029552853.sh: InProgress: not found

 

Независимо от того, что я пытаюсь обернуть условие if в, (), (()), [], [[]] Я получаю ту же ошибку, что и выше.

Не могли бы вы, пожалуйста, помочь мне решить эту проблему?

Ответ №1:

Используйте if [ "$instance_refresh_status" = "Successful" ]; then (обратите внимание на одиночные квадратные скобки и один знак равенства).

В вашей версии есть две проблемы: во-первых, (( )) это башизм, и ваш скрипт не работает под управлением bash. В любой оболочке, совместимой с POSIX ( ) , выполняется ее содержимое (как обычные команды оболочки) во вложенной оболочке. bash (и некоторые другие оболочки) обрабатываются (( )) по-разному, но в базовой оболочке POSIX, такой как dash (под которой, как я подозреваю, вы работаете), она просто запускает свое содержимое в двух слоях подоболочки. Таким образом, он работает "InProgress" == "Successful" в двойной вложенной оболочке, которая рассматривается InProgress как команда == и Successful как аргументы для нее, и получает сообщение об ошибке «не найдено» при поиске команды.

Если вы хотите использовать функции bash (или не знаете, какие функции являются функциями bash и которые будут работать в других оболочках), вам следует запустить сценарий с соответствующей строкой shebang для bash, например #!/bin/bash или #!/usr/bin/env bash (и не переопределяйте ее, запустив сценарий с sh помощью команды).

Вторая проблема заключается в том, что в bash (( )) выполняется целочисленная арифметическая оценка. Учитывая (( "InProgress" == "Successful" )) это , он попытается оценить InProgress и Successful как целые числа. Детали здесь не важны, но, по сути, они оба будут оцениваться как 0, поэтому, поскольку 0 == 0 это правда, тест будет верным, даже если это совершенно разные строки.

Для сравнения строк используйте [ ] или [[ ]] , и поскольку [[ ]] это еще один башизм (как == и внутри них), я бы рекомендовал использовать [ = ] его, по крайней мере, до тех пор, пока вы не будете уверены, в какой оболочке работает ваш скрипт.

Комментарии:

1. спасибо вам за ваш вклад. Я пробую это сейчас.. сообщу вам, как все прошло.

2. дааа! это сработало. Однако возникает вопрос, не приводит ли отсутствие пробелов после квадратных скобок к ошибке ?

3. @YYashwanth, shellcheck.net это твой друг

4. @YYashwanth Пробелы требуются между каждым элементом [ ] выражения, в том числе между скобками и сравниваемыми строками (в отличие от операторов присваивания, где пробелы вокруг = запрещены). И я поддерживаю рекомендацию shellcheck.net , так как это может указать на множество распространенных ошибок в написании сценариев.

5. В этом-то и была проблема. Я попробовал квадратные скобки, но я не расставил элементы, как показано ниже. Спасибо за помощь, и да, я сделал закладки в shellcheck.net. если [«$instance_refresh_status» = «Успешно»]