前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于 xargs 参数被截断,tar 文件被覆盖的问题

关于 xargs 参数被截断,tar 文件被覆盖的问题

作者头像
用户1177713
发布2018-02-24 11:08:55
1.6K0
发布2018-02-24 11:08:55
举报
文章被收录于专栏:数据之美

问题:

目录下共 2W+ 个小文件:

$ find . -type f | wc -l  

20083  

如果我们这样打包,会爆出 "Argument list too long" 的错误:

$ tar zcf test.tar.gz *  

-bash: /bin/tar: Argument list too long  

这是由于 * 展开后参数长度超过系统参数 ARG_MAX 的限制

为了不报这种错误,我们考虑用find的参数扩展来试试:

$ find . -type f -name "120150_*" | xargs tar zcvf 120150.tar.gz  

这个执行下来没有报错,但是 120150.tar.gz 中并没有包含全部的文件:

$ gzip -d 120150.tar.gz && tar tf 120150.tar | wc -l  

3407  

Linux 有个系统参数,用来控制命令行下参数的长度(包含环境数据),这个参数是 ARG_MAX ,在正式环境上是 131072 (bytes) :

$ getconf ARG_MAX  

131072  

    凡是超过 131072 bytes 长度的参数都会被截断, * 分批 * 传给 xargs 后面的参数。所以我猜想,第二批参数列表产生的压缩包把第一批参数列表产生的压缩包覆盖掉了,第三批又把第二批覆盖掉了。。。实际上只有最后一次传进来的参数被打进了压缩包中。

解决办法:

先追加打包所有文件,再压缩:

代码语言:javascript
复制
FILE_NUM=$(find . -type f | wc -l)  
logger "$BID FILE_NUM = $FILE_NUM"  
if [[ $FILE_NUM -gt $FILE_TRANSFER_LIMIT ]];then  
  logger "FILE_NUM More than $FILE_TRANSFER_LIMIT"  
  # 先用tar创建一个空的tar包,"tar cf null.tar" 会报错:"tar: Cowardly refusing to create an empty archive"  
  tar uf ./$BID.tar  
  # 用xargs追加进去所有的文件,这次不用怕被截断了~  
  find . -name "${BID}_*" | xargs tar uf ./$BID.tar  
  # 然后再压缩  
  gzip ./$BID.tar  
else  
  logger "FILE_NUM Less than $FILE_TRANSFER_LIMIT"  
  tar zcf ./$BID.tar.gz "$BID"_*  
fi

其实 xargs 这些用法的区别有些类似于 http 协议中 " 幂等 " 的概念, tar cf 这种命令是不 " 幂等 " 的, rm 这类的命令则是 " 幂等 " 的,有兴趣的同事可以参考这个链接: http://zh.wikipedia.org/wiki/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE#.E5.AE.89.E5.85.A8.E5.8F.8A.E5.B9.82.E7.AD.89.E6.96.B9.E6.B3.95 

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档