【问题标题】:Shell/Bash - positional parameter for script and function collidingShell/Bash - 脚本和函数碰撞的位置参数
【发布时间】:2021-11-06 15:19:48
【问题描述】:

我的脚本是接受一个参数dms。一旦获得,它就会创建多个变量,用作retry_cli 的参数。我遇到的问题是位置参数的使用。如何解决脚本创建变量并将其用作每个函数运行的参数的机制?

目前似乎该函数使用的是触发脚本时注入的位置参数,而不是在其中创建的参数。 Documentation 表示两个 $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 ]] && echo "connection status of $3 failed!" && 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

预期行为:

  1. 脚本运行:sh script.sh dms_name
  2. 每个dms_ 变量都会被填充
  3. retry_cli 使用 3 个参数调用。当$*_status不像success字符串时,函数必须用aws cli命令获取最新的status,只要返回success就重复
  4. 转到第二个函数调用

【问题讨论】:

    标签: bash amazon-web-services shell command-line-interface


    【解决方案1】:

    假设函数的 until 循环正在重复运行命令,直到它收到包含字符串 success 的状态消息。

    对于第一次传递,until 循环正在测试字符串 success 的函数的第一个输入参数 ($1)。

    until 循环的后续传递仍在测试字符串 success 的函数的第一个输入参数 ($1)。

    我猜你想要做的是测试最新的status 字符串success;如果是这种情况,那么也许是一个小的代码更改:

    retry_cli () {
        ...
        local status="$1"                           # new line
        until [[ "${status}" =~ "success" ]]        # modified line
        do
            ....
        done
        ...
    }
    

    如果这不能解决问题,那么 OP 可能希望提供有关该问题的更多详细信息(例如,循环永远不会退出,循环永远不会进入,???)。

    【讨论】:

    • 这个修改是否还记得检查status从函数调用到以后(如果错误)检查status从内部函数调用?
    • @marcin2x4 在建议的代码修改中status 是在本地定义的(对函数),因此对函数的每次调用都将从status 的新副本开始;如果您需要某种形式的 status 被“传递”到调用进程,那么我建议用这个事实更新问题以及如何在父脚本中使用所述值的示例;在这种情况下,我们可能希望考虑将 status 从局部变量更改为 nameref ......但在这一点上,如果这不能解决问题,我不想写得太过火
    • @marcin2x4 我认为这个答案仍然可以满足您的要求;你试过吗?如果它不符合您的要求,请提供一些有关错误/不正确的详细信息
    • 如果你的版本'工作',那是因为状态包括字符串success,甚至在函数被调用之前;在调用函数之前检查$ri_status$target_status 变量的内容;当前函数(如问题中所示)不可能收到不成功的字符串,通过循环,然后看到 $1 更改(只有 status 变量会更改,但不会更改在until 条件下进行测试);作为对当前代码的测试:unset ri_status; retry_cli "$ri_status" replication-instance-arn "$ri_arn"
    • 按照我在帖子中的解释工作。非常感谢@markp-fuso。好像和你解释的一样。当status 不是success 时,循环已启动,但status 中没有再次传递任何值。 AKA - 当它获得其他状态时,它没有在循环内传递。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 2012-09-21
    • 2018-09-07
    • 2013-10-26
    相关资源
    最近更新 更多