Bash递归目录打包脚本问题:重复输出与打包位置异常求助
解决Bash递归目录脚本的路径重复与tar包创建问题
问题原因分析
路径重复问题
脚本中echo语句错误拼接了当前目录路径与上一层循环的$f变量——Bash函数内变量默认全局,递归调用时$f未被重新赋值,导致路径出现重复目录名(比如进入Inbound目录后,$f仍保留上一层的Inbound值,最终输出/tmp/Inbound/Inbound)。
tar包未生成问题
- 不必要的引号转义(如
cd -- \"$f\";)导致cd命令尝试访问带引号的目录名,无法正确进入目标目录; - 反引号的错误转义(
\(pwd | awk...)`)导致无法获取当前目录名,PWD_DIR`变量为空,tar命令无有效输出文件名; - 未处理含空格/特殊字符的目录名,也未排除自身生成的tar包,存在逻辑漏洞。
修正后的脚本
#!/bin/bash recursive_for_loop() { # 遍历当前目录下所有可见目录(不含隐藏目录,若需处理可改为* .*) for f in ./*; do dir_name="${f#./}" # 仅处理真实目录,跳过符号链接 if [ -d "$f" ] && ! [ -L "$f" ]; then # 使用pushd/popd替代cd,避免目录切换失败后无法回退 pushd "$f" > /dev/null current_dir=$(basename "$PWD") echo "正在为目录 $PWD 创建压缩包" # 创建gzip压缩的tar包,排除自身避免重复打包 tar czf "${current_dir}.tar.gz" ./* --exclude="${current_dir}.tar.gz" # 递归处理子目录 recursive_for_loop popd > /dev/null fi done } recursive_for_loop
关键修改说明
- 修复路径重复:用
basename "$PWD"直接获取当前目录的真实名称,不再依赖上层循环变量,确保输出路径准确; - 可靠的目录切换:
pushd/popd比cd/cd ..更稳定,即使中间命令出错也能保证返回上一层目录; - 正确生成tar包:
- 用双引号包裹所有变量,兼容含空格/特殊字符的目录名;
- 添加
--exclude参数防止tar包被重复打包进自身; - 可选使用
czf生成压缩包(若不需要压缩可改回cvf);
- 逻辑优化:跳过符号链接避免循环遍历,明确遍历范围减少误操作。
预期效果
运行脚本后,每个子目录下会生成以自身目录名命名的tar包,输出路径示例:
正在为目录 /tmp/Inbound 创建压缩包 正在为目录 /tmp/Inbound/Lambda 创建压缩包 正在为目录 /tmp/Inbound/Lambda/app-inbound 创建压缩包 正在为目录 /tmp/Inbound/Lambda/app-outbound 创建压缩包
内容的提问来源于stack exchange,提问作者Gowmi
相关产品推荐
相关产品推荐

