优化含if..else条件迭代命令的Shell脚本,实现Pipeline指定步骤重启
优化Shell流水线脚本以消除重复代码
我们通过run.sh运行项目流水线,成功时能正常输出;流水线失败后,可通过给脚本传参数指定从某一步骤(如apple、banana等)重启执行,不用从头跑。但当前脚本用大量if-else分支实现该逻辑,重复代码多、维护麻烦,下面是优化方案:
原脚本代码
echo "Usage : file.sh step" if [ "$step" = "" ]; then python -u -m utils.py python -u -m apple.py python -u -m banana.py python -u -m cat.py python -u -m dog.py elif [ "$step" = "apple" ]; then python -u -m apple.py python -u -m banana.py python -u -m cat.py python -u -m dog.py elif [ "$step" = "banana" ]; then python -u -m banana.py python -u -m cat.py python -u -m dog.py elif [ "$step" = "cat" ]; then python -u -m cat.py python -u -m dog.py elif [ "$step" = "dog" ]; then python -u -m dog.py else echo "Issue" fi
优化后的脚本
#!/bin/bash # 按顺序定义所有流水线步骤 steps=("utils" "apple" "banana" "cat" "dog") step_arg="$1" # 输出使用说明 echo "Usage: $0 [step]" echo "可选step参数:${steps[*]}" # 确定起始执行的步骤索引 start_idx=0 if [ -n "$step_arg" ]; then # 校验传入的step是否合法 if ! [[ " ${steps[*]} " =~ " $step_arg " ]]; then echo "错误:无效的step参数,可选值为${steps[*]}" exit 1 fi # 找到起始步骤对应的数组索引 for i in "${!steps[@]}"; do if [ "${steps[$i]}" = "$step_arg" ]; then start_idx=$i break fi done fi # 从起始索引开始执行后续所有步骤 for ((i=start_idx; i<${#steps[@]}; i++)); do echo "执行步骤:${steps[$i]}" python -u -m "${steps[$i]}.py" # 步骤执行失败则立即终止流水线 if [ $? -ne 0 ]; then echo "步骤${steps[$i]}执行失败,流水线终止" exit 1 fi done echo "所有步骤执行完成"
优化说明
- 数组管理步骤:把所有流水线步骤按顺序存入数组,后续新增/调整步骤只需修改数组,无需改动分支判断,维护成本大幅降低
- 动态定位起始点:通过循环匹配传入参数,自动找到对应的起始执行位置,避免重复写执行命令
- 增加参数校验:如果传入的step不在合法列表中,直接报错退出,避免无效执行
- 失败终止逻辑:每一步执行后检查返回值,失败立即终止流水线,契合失败后重启的需求
- 友好输出提示:新增步骤执行状态提示,方便排查问题
执行示例:
- 从头执行流水线:
./run.sh - 从banana步骤开始执行:
./run.sh banana
内容的提问来源于stack exchange,提问作者Naresh
相关产品推荐
相关产品推荐

