递归实现ls -l与文件迁移Bash脚本问题:无限循环排查求助
我来帮你梳理下脚本里的问题,然后一步步解决这个无限循环+功能缺失的问题:
先说说你原脚本里的核心问题
- 遍历方式完全错误:
for i in ls -l "$1"这种写法根本不会执行ls -l命令,而是把字符串ls、-l和你的输入目录当成循环的三个元素,完全偏离了“遍历目录下文件/子目录”的需求。就算你改成for i in $(ls -l "$1"),ls -l输出的是带权限、日期的详细列表,$i会拿到一堆零散的字段(比如drwxr-xr-x、2),不是你要的文件名/目录名。 - 没处理目标目录参数:你的需求里明确要把文件移动到指定目录,但原脚本根本没接收这个参数,也没写移动逻辑。
- 无限循环的直接原因:就算你改成正确的遍历,要是没排除
.(当前目录)和..(上级目录)这两个特殊目录,脚本会递归调用处理当前目录,陷入无限循环。
修正后的完整脚本
这个脚本会实现你所有需求:显示目录内容、移动文件到指定目录、递归处理子目录,且不会无限循环:
#!/bin/bash # 检查用户是否传入了正确的参数(源目录+目标目录) if [ $# -ne 2 ]; then echo "用法: $0 <要处理的源目录> <文件要移动到的目标目录>" exit 1 fi source_dir="$1" target_dir="$2" # 先执行ls -l显示当前源目录的内容 echo "----------------------------------------" echo "当前处理目录: $source_dir" ls -l "$source_dir" echo "----------------------------------------" # 遍历源目录下的所有条目(不包含.和..) for item in "$source_dir"/*; do # 处理目录为空的情况:此时$source_dir/*会是原字符串,需要跳过 [ -e "$item" ] || continue item_name=$(basename "$item") target_item_path="$target_dir/$item_name" if [ -f "$item" ]; then # 如果是普通文件,移动到目标目录 echo "移动文件: $item -> $target_dir" # 加上-n可以避免覆盖已存在的文件,不需要的话可以去掉 mv -n "$item" "$target_dir/" elif [ -d "$item" ]; then # 如果是子目录,先在目标目录创建对应的子目录,再递归处理 mkdir -p "$target_item_path" echo "递归处理子目录: $item -> $target_item_path" bash "$0" "$item" "$target_item_path" fi done
脚本逻辑说明
- 参数校验:先检查用户是否传入了源目录和目标目录两个参数,避免误操作。
- 显示目录内容:每次处理一个目录时,先执行
ls -l展示内容,满足你的第一个需求。 - 安全遍历:用
"$source_dir"/*遍历目录下的所有条目,天然排除了.和..,从根源上避免无限循环。 - 文件移动:判断是普通文件时,直接移动到目标目录;如果是子目录,先在目标目录创建对应的子目录(
mkdir -p确保不管父目录是否存在都能创建),再递归调用脚本处理这个子目录。 - 避免覆盖:
mv命令加了-n参数,如果你不想覆盖目标目录已有的同名文件,可以保留;如果需要覆盖,去掉-n即可。
额外补充(可选)
如果你需要处理隐藏文件(以.开头的文件),可以把遍历部分改成下面这样,同时排除.和..:
for item in "$source_dir"/* "$source_dir"/.*; do [ -e "$item" ] || continue item_name=$(basename "$item") # 跳过.和..这两个特殊目录 if [ "$item_name" = "." ] || [ "$item_name" = ".." ]; then continue fi # 后面的处理逻辑不变... done
内容的提问来源于stack exchange,提问作者user9540477
相关产品推荐
相关产品推荐

