基于数组切换多目录的Bash脚本异常排查:单目录正常多目录失效
Bash脚本多目录批量压缩问题排查与修复
问题描述
我尝试用数组作为输入批量处理多个目录,已将两个目录路径赋值给变量start_dir。当仅传入单个目录路径时,脚本输出符合预期;但传入两个目录路径时,无法得到预期结果。
目录结构
└─# tree . ├── Inbound │ └── Lambda │ ├── app-inbound │ │ ├── inbound-primary.py │ │ └── requirements.txt │ └── app-inbound │ ├── inbound-primary.py │ └── requirements.txt └─# tree . ├── Outbound │ └── Lambda │ ├── app-Outbound │ │ ├── outbound-primary.py │ │ └── requirements.txt │ └── app-outbound │ ├── Outbound-primary.py │ └── requirements.txt
原脚本代码
#!/bin/bash start_dir=(/root/Outbound/Lambda/ /root/Inbound/Lambda) for d in "${start_dir[@]}"/*/ ; do echo "switch directory" cd "$d" || exit echo "Entring into location" for sub_dir in "${d[@]}" ; do echo "$sub_dir" zip -r "${sub_dir%/}".zip "$sub_dir" done done
问题分析
原脚本存在两个核心错误:
- 逻辑混乱的循环嵌套:外层循环已经遍历到具体子目录
$d,但内层循环错误地将单个字符串路径$d当作数组遍历("${d[@]}"),导致重复压缩当前目录,完全偏离预期逻辑。 - 工作目录未恢复:
cd "$d"后未返回初始目录,后续循环的目录切换会基于当前已变更的工作路径,大概率出现路径找不到的错误。
修正后的脚本
方案一:不切换目录直接压缩
#!/bin/bash start_dir=(/root/Outbound/Lambda /root/Inbound/Lambda) # 遍历每个起始根目录 for base_dir in "${start_dir[@]}"; do # 遍历根目录下的所有子目录 for sub_dir in "$base_dir"/*/; do # 跳过非目录项(避免无匹配时的通配符原样输出) [ -d "$sub_dir" ] || continue echo "正在压缩: $sub_dir" # 直接在原路径执行压缩,无需切换目录 zip -r "${sub_dir%/}".zip "$sub_dir" done done
方案二:使用子shell切换目录(自动恢复路径)
#!/bin/bash start_dir=(/root/Outbound/Lambda /root/Inbound/Lambda) for base_dir in "${start_dir[@]}"; do for sub_dir in "$base_dir"/*/; do [ -d "$sub_dir" ] || continue echo "进入目录: $sub_dir" # 子shell内执行cd和压缩,执行完自动回到原工作目录 (cd "$sub_dir" && zip -r "../${sub_dir##*/}.zip" .) || echo "压缩$sub_dir失败" done done
修正说明
- 拆分循环层级:先遍历根目录,再遍历根目录下的子目录,逻辑更清晰。
- 避免工作目录污染:要么直接在原路径压缩,要么用子shell隔离目录切换操作。
- 添加目录校验:过滤非目录项,避免无匹配子目录时的报错。
内容的提问来源于stack exchange,提问作者Gowmi
相关产品推荐
相关产品推荐

