Bash嵌套循环未逐次执行命令问题咨询
解决Bash脚本仅处理首个子文件夹的问题
这是Bash脚本遍历场景里挺常见的坑——你的循环能正常输出子文件夹名,但执行summary.sh时只跑了第一个,大概率是外部命令占用了标准输入(stdin),把循环后续的子文件夹名称给“吃掉”了。咱们一步步来搞定它:
问题根源拆解
当你用for循环或者find | while read的方式遍历子文件夹时,如果summary.sh内部有读取stdin的逻辑(比如不小心用了read命令但没指定输入源,或者它本身需要用户输入),就会把循环中剩下的子文件夹列表当作输入内容,导致循环直接终止,只执行第一次迭代。
假设你的原始脚本(基于症状推测)
大概率你的脚本是类似这样的:
#!/bin/bash # 遍历当前目录下的Folder_A.*子文件夹 for subdir in Folder_A.*; do echo "正在处理:$subdir" ./summary.sh # 这里就是问题触发点 done
或者用find管道的写法:
#!/bin/bash find . -type d -name "Folder_A.*" | while read subdir; do echo "正在处理:$subdir" ./summary.sh done
三种可行解决方案
方案1:给外部命令重定向stdin(最简单)
直接让summary.sh不要读取脚本循环的stdin,把它的输入重定向到/dev/null:
#!/bin/bash for subdir in Folder_A.*; do # 先判断是否为目录,避免匹配到非目录文件 if [ -d "$subdir" ]; then echo "正在处理:$subdir" ./summary.sh < /dev/null # 关键:切断stdin关联 fi done
方案2:用find -exec替代管道(更可靠)
如果用find的话,-exec选项可以避开管道和stdin冲突的问题,写法更稳健:
#!/bin/bash # -maxdepth 1 确保只找当前目录下的子文件夹,不递归更深层 find . -maxdepth 1 -type d -name "Folder_A.*" -exec sh -c ' for subdir do echo "正在处理:$subdir" ./summary.sh done ' sh {} +
方案3:检查summary.sh内部逻辑
如果summary.sh确实需要读取输入,但不是从循环的stdin,那可以修改它的输入来源:
- 比如它内部有
read命令,就明确指定输入文件(read < input.txt) - 去掉不必要的
read语句,避免它默认读取stdin
最后验证目录结构
确保你的目录层级是正确的(和你描述的一致):
Folder_A/ ├── Folder_A.1/ ├── Folder_A.2/ ├── 你的遍历脚本 └── summary.sh
执行脚本前,确认你在Folder_A目录下,或者在脚本里用绝对路径指向summary.sh和子文件夹。
这样修改后,脚本就能正常遍历所有子文件夹并执行summary.sh了。
内容的提问来源于stack exchange,提问作者CuriousDude
相关产品推荐
相关产品推荐

