Shell脚本递归遍历目录失效,tar打包移动功能异常求助
排查并修复你的tar打包移动脚本
嘿,我来帮你搞定这个脚本的问题,咱们一步步拆解为啥它没效果,再给你修正后的方案:
你的脚本存在的核心问题
- 循环逻辑完全失效:
第一个for directorio in $1循环只会把你传入的目标目录当成单个元素遍历一次,完全没实现递归遍历的效果;第二个for file in $directorio更是把目录名本身当成“文件”处理,根本没进入目录去遍历里面的内容。 - tar命令用错了:
你写的tar -czPf "$fwe.tar.bz2" "$(pwd)"是把当前整个工作目录打包成压缩包,而不是你想要的单个文件/子目录;而且-P参数会保留绝对路径,解压时可能直接覆盖系统对应路径的内容,风险很高。 - 变量处理逻辑不匹配:
fwe="${file%.*}"是用来去掉文件后缀的,但如果file是目录名,这个操作毫无意义;而且你用这个变量命名压缩包,却打包了整个当前目录,逻辑完全对不上。
修正后的脚本(两种场景可选)
先明确需求:递归遍历你传入的目标目录,把每个文件/子目录单独打包成.tar.bz2,再移动到/home/cunha/teste目录。这里给你两种常见场景的实现:
场景1:递归打包所有单个文件
适合需要把目录里的每个文件单独压缩的情况:
#!/bin/bash # 检查是否传入了目标目录参数 if [ $# -ne 1 ]; then echo "用法: $0 <目标目录>" exit 1 fi target_dir="/home/cunha/teste" # 确保目标目录存在,不存在就创建 mkdir -p "$target_dir" # 递归遍历目录下的所有文件(跳过目录) find "$1" -type f | while read -r file; do # 获取不带路径的文件名 filename=$(basename "$file") # 去掉文件名的后缀 fwe="${filename%.*}" # 打包单个文件,用-C切换到文件所在目录,避免打包绝对路径 tar -cjf "$fwe.tar.bz2" -C "$(dirname "$file")" "$filename" # 移动压缩包到目标目录,若要避免覆盖可加-n参数:mv -n ... mv "$fwe.tar.bz2" "$target_dir/" done
场景2:递归打包所有子目录
适合需要把每个子目录单独压缩的情况:
#!/bin/bash if [ $# -ne 1 ]; then echo "用法: $0 <目标目录>" exit 1 fi target_dir="/home/cunha/teste" mkdir -p "$target_dir" # 递归遍历目录下的所有子目录(跳过传入的根目录本身) find "$1" -mindepth 1 -type d | while read -r dir; do # 获取不带路径的目录名 dirname=$(basename "$dir") # 打包子目录,同样用-C切换路径避免绝对路径 tar -cjf "$dirname.tar.bz2" -C "$(dirname "$dir")" "$dirname" mv "$dirname.tar.bz2" "$target_dir/" done
关键改进说明
- 用
find命令实现可靠的递归遍历,这是bash中处理目录递归最省心的方式,不用自己写嵌套循环。 tar命令加了-C参数,切换到文件/目录所在路径后再打包,这样压缩包里不会带绝对路径,解压时更安全灵活。- 加了参数检查和目标目录自动创建,避免因参数错误或目录不存在导致脚本崩溃。
- 用
read -r处理文件名/目录名,能兼容包含空格的路径,不会出现截断问题。
调用方式
比如你要处理/home/cunha/myfiles这个目录,直接运行:
./script.sh /home/cunha/myfiles
内容的提问来源于stack exchange,提问作者user9540477
相关产品推荐
相关产品推荐

