cat/Xargs/command VS for/bash/command

6
书籍《Linux 101 Hacks》的第38页建议如下:
cat url-list.txt | xargs wget –c

我通常做:

for i in `cat url-list.txt`
   do
      wget -c $i
   done 

除了长度之外,xargs技巧在bash中是否比旧的for循环技巧更优?

添加

C源代码似乎只有一个fork。相比之下,bash组合有多少个forks呢?请详细解释该问题。

7个回答

4

xargs旨在为每个分支进程处理多个输入。使用for循环遍历其输入的shell脚本必须为每个输入分叉一个新进程。避免每个进程的开销可以大大提高xargs解决方案的性能。


1
你的意思是xargs仅用于性能优化吗?很难相信。一定还有其他用途。 - Léo Léopold Hertz 준영
它的输入也相对较短。并且有一个大标签上写着“不要惊慌”。 - kdgregory
2
而且说实话:进程创建并不便宜。在今天的快速处理器上,这是不可感知的,但回到10-15年前,你就可以看到为什么xargs是首选解决方案。 - kdgregory
“只是为了性能?”不要忘记,xargs 还可以处理那些无法处理大量参数的命令。 - Dennis Williamson

4
UNIX手册页的Rationale部分可以看出,xargs实用程序的经典应用是与find实用程序结合使用,以减少通过find -exec组合启动的进程数量。 xargs实用程序还用于强制执行启动进程所需的内存上限。考虑到这一基础,POSIX.1-2008卷仅选择了必需的最小功能。
在您的后续问题中,您问其他版本将有多少个fork。 Jim已经回答了这个问题:每次迭代一个。有多少次迭代?无法给出确切数字,但很容易回答一般问题。您的url-list.txt文件中有多少行?
还有其他一些考虑因素。 xargs对具有空格或其他禁止字符的文件名需要额外的注意,而-exec具有一个选项(+),可以将处理分组成批处理。因此,并非每个人都喜欢xargs,也许它并不适合所有情况。
请参见以下链接:

4

还需考虑以下内容:

xargs -I'{}' wget -c '{}' < url-list.txt

但是wget提供了更好的方法来实现相同的功能:
wget -c -i url-list.txt

关于使用xargs还是循环的考虑,我更喜欢在意义和实现相对“简单”和“清晰”的情况下使用xargs,否则我会使用循环。


4

xargs还允许您拥有一个巨大的列表,而“for”版本无法实现,因为shell使用长度有限的命令行。


这是我听到的唯一令人信服的理由之一,假设它是正确的且不过时的信息。 - ThorSummoner

2

我更喜欢使用xargs内置的并行处理,而不是GNU/Parallel。加上-P指定要并行执行的进程数,例如...

 seq 1 10 | xargs -n 1 -P 3 echo

计算时会使用3个不同核心上的3个进程。现代GNU Xargs支持此功能。如果要使用BSD或Solaris,请自行验证。


1

0

我能想到的一个优点是,如果你有很多文件,使用bash可能会稍微快一些,因为你不需要启动新进程带来的额外开销。

但我并不是一个bash专家,所以它可能还有其他更好(或更差)的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接