Shell脚本:如何将循环输出传入xargs生成目标tar文件?
解决tar文件未生成的问题:正确传递循环输出给xargs
原脚本的核心问题
- 输入传递断裂:for循环的输出未通过管道连接到xargs,两者是独立执行的命令,导致xargs没有接收到任何文件路径。
- 语法错误:
if [$length != 0 ];then缺少空格,正确写法应为if [ $length != 0 ];then;针对数值比较,用-ne(不等于)更严谨。 - 未处理特殊字符:
find $dir未加双引号,当目录名包含空格或特殊字符时会被错误拆分。 - tar参数顺序问题:
tar cvfz mpe-tar/$i/part_2.tgz中f参数需要紧跟输出文件路径,否则xargs传递的文件会被误判为输出文件名。 - 未定义变量:
$i变量未声明,会导致路径拼接错误。
修正后的基础版本
path3="A/B/C" # 用-ne做数值比较,变量加引号避免空值问题 if [ "$length" -ne 0 ]; then # 用while read替代for循环,兼容含空格的目录名 find "$path3" -type d | while read -r dir; do # 给dir加引号,限制查找深度为1,取最后length个文件 find "$dir" -maxdepth 1 -type f | tail -n "$length" done | xargs tar cvzf "mpe-tar/${i:-default}/part_2.tgz" fi
支持特殊字符的稳健版本
如果文件名/目录名包含换行、空格等特殊字符,建议用null分隔符处理,避免解析错误:
path3="A/B/C" if [ "$length" -gt 0 ]; then # -print0用null分隔目录名,read -d ''读取null分隔的内容 find "$path3" -type d -print0 | while IFS= read -r -d '' dir; do # -print0输出null分隔的文件名,tail -z处理null分隔的输入 find "$dir" -maxdepth 1 -type f -print0 | tail -z -n "$length" done | xargs -0 tar cvzf "mpe-tar/${i:-default}/part_2.tgz" fi
关键修正说明
- 将整个循环的输出通过管道直接传递给xargs,确保xargs能获取所有选中的文件路径。
- 所有变量和路径都添加双引号,避免特殊字符导致的解析错误。
tail -n明确指定行数,避免环境差异。${i:-default}作为兜底,若$i未定义则使用default作为目录名,防止路径无效。
内容的提问来源于stack exchange,提问作者Prashant Kumar Jha
相关产品推荐
相关产品推荐

