#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» = «Успешно»]