如何在shell脚本中调用指定目录下所有shell脚本并解决无限循环问题
问题根因
- 逻辑重复触发:你已经在遍历目标目录下的每个文件,一旦匹配到
.sh后缀文件就执行bash "$d"/*.sh,相当于每识别到1个sh文件,就会把整个目录下的所有sh文件全部执行一遍。如果目录下有N个sh文件,就会重复触发N次全量执行,出现类似循环的效果。 - 路径处理冗余:你已经通过
cd $d进入了目标子目录,后续操作不需要再拼接$d前缀,路径错误也可能导致脚本重复调用。 - 未排除主脚本自身:如果你当前运行的主脚本也在遍历的目录范围内,会出现脚本反复调用自己的情况,导致真正的无限循环。
修正后的实现代码
for d in "$dir"/*/ ; do echo "处理目录 $d" # tools目录单独处理,跳过sh执行 if [[ "$d" == *"tools/" ]]; then echo "跳过tools目录的sh执行" for f in "$d"/*.yaml; do [ -f "$f" ] || continue python3 -c 'import yaml, sys; print(yaml.safe_load(sys.stdin))' < "$f" done continue fi # 逐个执行sh文件 for sh_file in "$d"/*.sh; do # 跳过不存在的匹配项、以及当前运行的主脚本自身 [ -f "$sh_file" ] || continue [ "$sh_file" -ef "$0" ] && continue echo "执行脚本:$sh_file" bash "$sh_file" done # 逐个解析yaml文件 for yaml_file in "$d"/*.yaml; do [ -f "$yaml_file" ] || continue echo "解析yaml文件:$yaml_file" python3 -c 'import yaml, sys; print(yaml.safe_load(sys.stdin))' < "$yaml_file" done done
关键优化点
- 取消了嵌套的
cd操作,直接用全路径匹配文件,避免路径切换出错 - 把sh文件和yaml文件的遍历逻辑拆分,不会出现每匹配一个文件就触发全量执行的问题
- 增加了文件存在性判断,避免通配符没有匹配到文件时把通配符本身当文件名执行
- 增加了主脚本自身的排除判断,避免自我调用导致无限循环
- 单独处理tools目录逻辑,不需要在文件遍历的时候重复判断目录属性
内容的提问来源于stack exchange,提问作者Fernando Couto
相关产品推荐
相关产品推荐

