Shell/Bash脚本与函数位置参数冲突,如何实现预期重试功能?
Bash脚本问题修复方案
核心问题
你遇到的不是位置参数作用域冲突问题,而是逻辑判断错误:调用retry_cli时传入的$ri_status/$target_status是函数执行前一次性查询的静态值,函数循环内更新的status变量没有被用于判断条件,until [[ $1 =~ "success" ]]永远判断的是首次传入的旧状态值,导致逻辑不符合预期。
具体修复点
- 调整
retry_cli的判断逻辑,直接使用循环内查询到的最新status值做判断,不需要传入初始状态参数 - 补全所有变量引用的双引号,避免特殊字符/空格导致的执行异常
- 修正计数器判断的语法,补充
$符取值 - 替换反引号为更规范的
$()命令替换写法 - 修正输出文本的拼写错误
修复后完整代码
#!/bin/bash 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") retry_cli () { local max_retry=100 local counter=0 local sleep_seconds=15 local aws_region="us-east-1" local filter_name=$1 local resource_arn=$2 local status until [[ $status =~ "success" ]] do status=$(aws dms describe-connections --filter Name="$filter_name",Values="$resource_arn" --query=Connections[0].Status --region "$aws_region") [[ $counter -eq $max_retry ]] && echo "connection status of $resource_arn failed!" && exit 1 ((counter++)) sleep $sleep_seconds done echo "connection for $resource_arn OK!" } retry_cli replication-instance-arn "$ri_arn" retry_cli endpoint-arn "$target_arn" echo "starting dms" aws dms start-replication-task --replication-task-arn "$dms_arn" --start-replication-task-type resume-processing --region "$aws_region" echo "done"
执行逻辑说明
- 执行
bash script.sh dms_name启动脚本(建议指定bash解释器避免sh兼容问题) - 所有DMS相关资源ARN会先完成赋值
- 调用
retry_cli时只需传入过滤字段名和资源ARN,函数内部会循环查询最新状态,直到返回包含success的结果,重试100次失败则自动退出 - 两个函数调用按顺序串行执行,全部完成后才会启动DMS任务
内容的提问来源于stack exchange,提问作者marcin2x4
相关产品推荐
相关产品推荐

