【问题标题】:`tar` slow performance through `xargs``tar` 通过`xargs` 降低性能
【发布时间】:2012-03-10 07:57:23
【问题描述】:

请考虑这个sn-p:

tar -Oxvf archive.tgz | grep something

或者这个:

tar tf archive.tgz > /tmp/x && tar -Oxvf archive.tgz -T /tmp/x | grep something

相对于这个:

tar tf archive.tgz | xargs -I{} tar -Oxvf archive.tgz {} | grep something

前两个 sn-ps 非常快且相似,而第三个慢了约 40 倍(我猜这个索引是相对于存档内容的)。这是为什么呢?

【问题讨论】:

  • 似乎在使用-T 开关时,tar 在自己的规则下一次读取列表并提取文件(即它不像/tmp/x 文件列表那样按顺序提取,但是为了它们被压缩),而当使用xargs时,惩罚是从顺序执行中获得的。即使这是真的,恕我直言,这也太慢了

标签: shell tar xargs


【解决方案1】:

这里的关键是您在 xargs 中使用 -I{}。手册页说:

   -I replace-str

将初始参数中出现的 replace-str 替换为从标准输入中读取的名称。此外,未引用的空白不 终止输入项;相反,分隔符是换行符。 暗示 -x 和 -L 1

隐含的-L 1 使xargs 对存档中的每个文件运行一次tar -Oxvf archive.tgz {},而不是运行一次 tar 以提取 xargs 的标准输入中列出的所有文件。

差异的简化示例:

$ (echo foo; echo bar)|xargs -I{} echo {}
foo
bar

$ (echo foo; echo bar)|xargs echo 
foo bar

固定:

tar tf archive.tgz | xargs tar -Oxvf archive.tgz | grep something

但是请注意,如果提供给 xargs 的文件名不是 tar 文件顺序(即与 tar t 列出它们的顺序相同),则此输出与使用 xargs -I{} 得到的输出不同)。 xargs -I{} 版本将按照您提供给 xargs 的顺序输出文件,而此版本将按照 tar 文件顺序输出它们。

【讨论】:

  • 好的。这当然是对所提问题的正确答案,但我想评论一下,tar tf archive.tgz | sort | xargs tar -Oxvf archive.tgz 在输出时不会对存档中的文件进行排序,而tar tf archive.tgz | sort | xargs -I{} tar -Oxvf archive.tgz {} 将进行排序,并且由于您解释的原因而受到时间惩罚。谢谢
  • @theta 点 - 我实际上考虑在其中添加关于潜在排序更改的注释,但决定反对,因为tar tf 将始终生成与tar x 提取它们相同的顺序。事后看来这是一个糟糕的决定,因为这显然是一个简化的示例。
【解决方案2】:

我有点不确定你想用你的例子实现什么。我不明白第一个示例中的第一个管道应该实现什么,因为没有使用通过管道传输到第二个 tar 的输出。 && 似乎是加入两个命令的更好方法(只有在第一个成功时才执行第二个)。除此之外,如果您使用完整的文件列表进行提取(并且仅用于该任务),如您的示例中所示,则无需花费单独的 tar 运行来创建它,因为 tar 默认情况下会提取所有文件,除非另有说明。

就速度而言 - 管道接收端的 tar 没有特殊方法来区分它获得的输入是否来自另一个 tar 以进行优化。不同之处在于,在两个 tar 命令的情况下,第一个将立即开始其输出,因此第二个 tar 可以开始运行,而 xargs 将首先收集所有数据,然后开始其输出和馈送焦油安排在它后面运行。

如果您正在寻找一种从 tar 存档中仅提取文件子集的快速方法,并希望按文件名进行选择,我建议您使用 star,它有一个内置的 find 命令。

【讨论】:

  • 哎呀,你是对的,我添加了&&。我的问题是我的文件以未排序的顺序存储在 tar 存档中 - 这就是它们的创建方式 - 我需要输出(grep)遍历 tar 存档内容但按排序顺序。事实证明,tar 无法按照存储顺序提取文件,毕竟tar 被设计为 Tape ARchiver。如前所述,tar 也不尊重文件列表中指向的文件的顺序(-T 开关)——它一次提取,如果文件在列表中的任何位置,它就会提取
  • @theta 它也不尊重多个命令行参数的顺序,它们的行为就像-T。问题是xargs -I{}(见我的回答)
猜你喜欢
  • 2020-06-02
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 2019-07-06
  • 2019-11-15
  • 2018-12-12
相关资源
最近更新 更多