Ubuntu Bash中如何遍历动态变化的文件列表?
这问题我太熟了——shell里的glob展开(就是你用的"$1"/*)是在命令执行前就完成的,所以一开始的for循环会把当时存在的文件都列成固定数组,后面caseit新增的文件自然不在这个数组里,根本不会被处理。给你几个实用的解决方案,按需选:
解决方案1:用while read配合动态文件列表(最通用)
替换原来的for循环,每次循环都实时获取当前目录的文件,而不是一开始就固定死列表。推荐用find配合空字符分隔来处理特殊文件名(比如带空格、换行的文件名):
# 替换你原来的for file in "$1"/* 这段代码 find "$1" -maxdepth 1 -mindepth 1 -print0 | while IFS= read -r -d '' file; do # 这里放你原来对$file的处理逻辑 if [ -d "$file" ]; then vacatetmp "$file" # 递归处理子目录 else caseit "$file" # 处理文件,可能生成新文件 fi done
-maxdepth 1确保只遍历当前目录(和你原来的for循环逻辑一致,递归交给vacatetmp)-mindepth 1排除目录本身(避免处理$1自己)-print0和read -d ''是为了安全处理各种奇葩文件名,不会因为空格、引号之类的字符出错
解决方案2:用find直接递归处理(简化逻辑)
如果你的vacatetmp递归逻辑可以整合到find里,直接让find实时遍历整个目录树——它会动态扫描文件系统,所以caseit新增的文件只要在遍历路径里,后续都会被扫到:
# 先处理子目录内容,再处理目录本身(和递归函数顺序一致) find "$1" -depth -exec your_processing_logic {} \;
举个具体点的例子,如果你需要区分文件和目录:
find "$1" -depth -type f -exec caseit {} \; find "$1" -depth -type d -exec some_directory_logic {} \;
这种方式代码更简洁,适合逻辑不复杂的场景。
解决方案3:循环扫描直到没有新文件(适合批量生成场景)
如果caseit会一次性生成一批新文件,你可以循环扫描目录,直到两次扫描的文件数量一致,确保所有新增文件都被处理:
prev_file_count=0 current_file_count=$(find "$1" -type f | wc -l) while [ "$current_file_count" -ne "$prev_file_count" ]; do prev_file_count=$current_file_count # 遍历所有未处理的文件 find "$1" -maxdepth 1 -mindepth 1 -print0 | while IFS= read -r -d '' file; do if [ -d "$file" ]; then vacatetmp "$file" else # 加个标记避免重复处理已完成的文件 if [ ! -f "$file".processed ]; then caseit "$file" touch "$file".processed fi fi done # 更新当前文件数量 current_file_count=$(find "$1" -type f | wc -l) done
注意:这个方法适合小目录,大目录下频繁find会有点慢,而且要记得清理.processed标记文件,避免后续运行出问题。
额外提醒
如果你的vacatetmp函数内部也是用类似的for file in "$dir"/*循环,那也要同步改成动态遍历的方式,不然递归到子目录时会遇到同样的问题哦!
内容的提问来源于stack exchange,提问作者sheikhness
相关产品推荐
相关产品推荐

