使用tar命令压缩变量存储的文件列表时报文件名过长错误如何解决
问题根因
你的报错确实和变量存储方式直接相关,除此之外原脚本还有多处逻辑错误:
- 你把
unmodified存为普通字符串变量,给tar传参时用双引号包裹后,tar会把所有拼接在一起的文件名当做单个超长文件名处理,自然触发「文件名过长」报错 - 筛选最早5个文件的逻辑完全颠倒:sort默认按时间升序排列,最早修改的文件在结果顶部,原脚本用
tail -n 5取的是最晚修改的5个文件,和需求完全相反 - 筛选结果里带时间戳字段,循环遍历时会把时间戳也当做独立条目,根本找不到对应文件,权限修改逻辑完全不生效
- 两处find都只用了
%f输出纯文件名,没有保留路径,如果文件在子目录下,后续操作根本找不到对应文件 - 用
xargs -0读取换行分隔的find输出,参数匹配错误,会把所有换行当做普通字符拼接到同一个字符串里 - 没有提前创建
~/Main/Backup目录,tar输出路径不存在也会报错 - chmod加了不必要的
-R参数,你已经筛选了-type f普通文件,不需要递归操作
修正后可运行的完整脚本
#!/bin/bash # 先确保备份目录存在 mkdir -p ~/Main/Backup echo "修改时间最早的5个文件: " echo "--------------------" # 直接把最早的5个文件的完整路径存到数组,排除时间戳干扰 mapfile -t earliest_files < <(find ~/Main/ -type f -printf '%T+ %p\n' | sort | head -n 5 | awk '{print $2}') printf "%s\n" "${earliest_files[@]}" # 批量修改这5个文件的权限为744 chmod 744 "${earliest_files[@]}" echo "权限未修改的文件: " echo "-----------------------" # 把未修改权限的文件完整路径存到数组,用null分隔兼容含特殊字符的文件名 mapfile -d '' unmodified < <(find ~/Main/ -maxdepth 2 -type f ! -perm 744 -print0) printf "%s\n" "${unmodified[@]}" # 直接把数组传给tar,每个文件名都是独立参数 tar -czvf ~/Main/Backup/Archive1.tar.gz "${unmodified[@]}"
关键改动说明
- 用
mapfile(bash 4.0+支持,主流Linux发行版都自带)直接把find结果存到数组,每个文件名作为数组的独立元素,不会出现拼接成单个字符串的问题 - find输出用
%p代替%f,保留文件完整路径,确保后续操作能定位到文件 - 筛选最早5个文件时先按时间升序排序,用
head -n 5取顶部5条结果,符合需求 - 查找未修改权限的文件时用
-print0以null字符分隔文件名,搭配mapfile -d ''读取,完美兼容含空格、换行等特殊字符的文件名 - 传参给tar的时候用
"${数组名[@]}"的格式,会自动把每个数组元素作为独立参数传递,不会触发长文件名错误
内容的提问来源于stack exchange,提问作者Hulk is TRASH
相关产品推荐
相关产品推荐

