#bash #amazon-web-services #shell #command-line-interface
Вопрос:
Мой сценарий должен принимать один параметр dms
. После получения он создает несколько переменных, которые используются в качестве аргумента для retry_cli
. Проблема, с которой я сталкиваюсь, связана с использованием позиционных параметров. Как обойти механизм создания скриптом переменных и использовать их в качестве параметров для запуска каждой функции?
В настоящее время кажется, что функция использует позиционные параметры, вводимые при запуске скрипта, а не те, которые созданы внутри него. В документации указано, что два $1
позиционных аргумента (для скрипта и функции) не должны быть проблемой.
dms_name=$1
aws_region="us-east-1"
dms_arn=`aws dms describe-replication-tasks --filter Name=replication-task-id,Values="$dms_name" --query=ReplicationTasks[0].ReplicationTaskArn --output text --region "$aws_region"`
ri_arn=`aws dms describe-replication-tasks --filter Name=replication-task-id,Values=$dms_name --query=ReplicationTasks[0].ReplicationInstanceArn --region "$aws_region"`
target_arn=`aws dms describe-replication-tasks --filter Name=replication-task-id,Values=$dms_name --query=ReplicationTasks[0].TargetEndpointArn --region "$aws_region"`
ri_status=`aws dms describe-connections --filter Name=replication-instance-arn,Values=$ri_arn --query=Connections[0].Status --region "$aws_region"`
target_status=`aws dms describe-connections --filter Name=endpoint-arn,Values=$target_arn --query=Connections[0].Status --region "$aws_region"`
retry_cli () {
local max_retry=100
local counter=0
local sleep_seconds=15
local aws_region="us-east-1"
until [[ $1 =~ "success" ]]
do
status=`aws dms describe-connections --filter Name=$2,Values="$3" --query=Connections[0].Status --region "$aws_region"`
[[ counter -eq $max_retry ]] amp;amp; echo "connection status of $3 failed!" amp;amp; exit 1
((counter ))
sleep $sleep_seconds
done
echo "connection for $3 OK!"
}
retry_cli "$ri_status" replication-instance-arn "$ri_arn"
retry_cli "$target_status" endpoint-arn "$target_arn"
echo startting dms
aws dms start-replication-task --replication-task-arn "$dms_arn" --start-replication-task-type resume-processing --region "$aws_region"
echo done
Ожидаемое поведение:
- скрипт запущен:
sh script.sh dms_name
- заполняется каждая
dms_
переменная retry_cli
вызывается с 3 аргументами. Если$*_status
это не похожеsuccess
на строку, то функция должна получить последнююstatus
сaws cli
помощью command и повторять ее до тех пор, пока она не вернетсяsuccess
- переход ко второму вызову функции
Ответ №1:
Я предполагаю, что цикл функции until
выполняет повторный запуск команды до тех пор, пока не получит сообщение о состоянии, включающее строку success
.
Для первого прохода until
цикл проверяет первый входной параметр функции ( $1
) для строки success
.
Последующие проходы через until
цикл все еще проверяют первый входной параметр функции ( $1
) для строки success
.
Я предполагаю, что для последующих проходов вы хотите проверить последнюю status
версию строки success
; если это так, то, возможно, небольшое изменение кода:
retry_cli () {
...
local status="$1" # new line
until [[ "${status}" =~ "success" ]] # modified line
do
....
done
...
}
Если это не решает проблему, то OP может захотеть предоставить более подробную информацию о проблеме (например, цикл никогда не завершается, цикл никогда не вводится, ???).
Комментарии:
1. Будет ли эта модификация по-прежнему помнить о проверке
status
из вызова функции для последующей проверки (в случае ошибки)status
из внутреннего вызова функции?2. @marcin2x4 в предлагаемой модификации кода
status
определяется локально (для функции), поэтому каждый вызов функции будет начинаться с новой копииstatus
; если вам нужна какая-то формаstatus
, которая должна быть «передана» вызывающему процессу, тогда я бы предложил обновить вопрос с учетом этого факта, а также с помощьюпример того, как вы используете указанные значения в родительском скрипте; в таком сценарии мы, вероятно, захотим рассмотреть переходstatus
от локальной переменной к nameref … но на данный момент я не хочу переусердствовать с написанием этого, если это не решает проблему3. @marcin2x4 Я думаю, что этот ответ по-прежнему делает то, что вы хотите; вы пробовали? если он не выполняет то, что вы хотите, пожалуйста, предоставьте некоторые подробности о том, что не так / неправильно
4. если ваша версия «работала», это потому, что статус включал строку еще
success
до того, как функция была вызвана; проверьте содержимое ваших$ri_status
$target_status
переменных и перед вызовом функции; текущая функция (как показано в вопросе) никак не получит строку с ошибкой, выполните проходпройдите цикл и посмотрите$1
изменения (изменится толькоstatus
переменная, и она не проверяется вuntil
условии); в качестве проверки текущего кода:unset ri_status; retry_cli "$ri_status" replication-instance-arn "$ri_arn"
5. Работает так, как я объяснил в сообщении. Большое спасибо @markp-fuso. Похоже, как вы объяснили. Когда
status
неsuccess
было, цикл был инициирован, но в нем не было повторно передано значениеstatus
. Иначе — когда он получил другой статус, он не был передан внутри цикла.