免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: netcafe
打印 上一主题 下一主题

xargs的一个问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-08-01 23:25 |只看该作者
原帖由 eeeef 于 2008-8-1 23:16 发表
没说是管道造成的问题。是因为你目录下的文件太多,没加xargs的时候,grep就想一口气吃一个大胖子,结果憋死了。xargs的作用就在于,它会按照自己的能力来吃,比如一次性只吃100个,再吃100个...........
这个 ...


你的说法,同 爱知  的说法。 也是 grep 执行了若干次?

论坛徽章:
0
12 [报告]
发表于 2008-08-01 23:26 |只看该作者
原帖由 netcafe 于 2008-8-1 23:08 发表


照你的意思, ls | xargs grep "pattern" 会把10000个文件若干批,假设为5,每次为2000个,功执行了5次grep 操作?
把grep 命令换成你自己的命令,或者一个脚本,打印一些信息,发现它会执行1次。


xargs的确可以解决你说的这种“参数过长”的问题,但它没必要做成让大家认为它执行了N次的样子。它就像一个黑盒,解决了问题,呈现出有他无他一样的效果,如果这个命令是我来设计,我也会这么做的,难道我非得设计成让他们看看我执行了几次的样子,至于你说的执行几次操作,可以用-n命令来规范一次操作的参数数,达到相同的效果。如果没有指定,它只会消除这种影响,不会自作聪明的告诉大家我xargs就是这样来规避难题的。

论坛徽章:
0
13 [报告]
发表于 2008-08-01 23:31 |只看该作者
原帖由 netcafe 于 2008-8-1 23:25 发表


你的说法,同 爱知  的说法。 也是 grep 执行了若干次?


论坛徽章:
0
14 [报告]
发表于 2008-08-01 23:32 |只看该作者
貌似如果文件更多的话,单纯的ls也会有这样的问题

还是应该是shell解释的原因,比如超过了什么限制。

论坛徽章:
0
15 [报告]
发表于 2008-08-01 23:50 |只看该作者
原帖由 eeeef 于 2008-8-1 23:26 发表


xargs的确可以解决你说的这种“参数过长”的问题,但它没必要做成让大家认为它执行了N次的样子。它就像一个黑盒,解决了问题,呈现出有他无他一样的效果,如果这个命令是我来设计,我也会这么做的,难道我非 ...



>> 如果这个命令是我来设计,我也会这么做的
这里是否更多是你的“主观臆测”还是确实有所依据?

我们把 ls | xargs grep "pattern" 中的 grep 换成一个自己的bin或者shell,
假设 yourscript.sh 内容如下:
#!/bin/sh
echo $1000
echo $#

然后 ls | xargs yourscript.sh ,发现它确实打印了第1000个参数(只打印一次),也打印了参数的总个数10000(只打印一次)。
无法证明,yourscript.sh 被分成了好几次执行。

论坛徽章:
0
16 [报告]
发表于 2008-08-02 02:10 |只看该作者

回复 #15 netcafe 的帖子

的确是主观臆测,请看下楼

[ 本帖最后由 eeeef 于 2008-8-2 02:50 编辑 ]

论坛徽章:
0
17 [报告]
发表于 2008-08-02 02:49 |只看该作者
xargs 命令限制命令行的长度。当构造的命令行运行时,组合的 Argument 和环境列表不能超过 ARG_MAX 字节。在这一约束里,如果不指定 -n 或 -s 标志,缺省命令行长度至少是 LINE_MAX 指定的值。
-n Number运行 Command 参数,且使用尽可能多的标准输入自变量,直到 Number 参数指定的最大值。xargs 命令使用很少的自变量,如果: 如果被积累的命令行长度超过了由 -s Size 标志指定的字节。 最后的迭代有少于 Number(但是非零)的自变量保留。


首先我推翻我先前说过的言论。
测试如下:
seq 100000 | xargs touch   创建10万个文件,然后作为一个组合的参数,依然没有报错,显然是并没有超过ARG_MAX 字节,缺省命令行长度也没有超过LINE_MAX的值。对于它们的值是多少,我不敢说,总之得出的结论是:这个值很大,并且可能和系统环境有关。
测试如下:
ls | xargs -n4 ./yourscript.sh
ls | xargs -s60 ./yourscript.sh
都可以很明显的看出xargs是按照-n或者-s来划分区域,而yourscript.sh脚本则被执行了多次,这点推翻了我的说法

而当不指定-n和-s的时候,且不超过ARG_MAX 字节和LINE_MAX的时候,则yourscipt.sh只被执行了一次,我们以ls | ./yourscipt.sh是否报错为界限,如果它都没有报错,那么说明它可以承受这个长度,当然只需要执行一次。如果报错,加xargs,它划分为多次来执行,这点没错。

[ 本帖最后由 eeeef 于 2008-8-2 02:51 编辑 ]

论坛徽章:
0
18 [报告]
发表于 2008-08-02 02:55 |只看该作者
原帖由 netcafe 于 2008-8-1 23:50 发表



>> 我们把 ls | xargs grep "pattern" 中的 grep 换成一个自己的bin或者shell,
假设 yourscript.sh 内容如下:
#!/bin/sh
echo $1000
echo $#

然后 ls | xargs yourscript.sh ,发现它确实打印了第1000个参数(只打印一次),也打印了参数的总个数10000(只打印一次)。
无法证明,yourscript.sh 被分成了好几次执行。


这里,LZ不妨试一试 ls | yourscript.sh 是否有报错,如果没有报错,说明系统是可以承受这个长度的,那么即使你加xargs,它仍然会一次性执行。

论坛徽章:
0
19 [报告]
发表于 2008-08-02 11:35 |只看该作者
原帖由 welcome008 于 2008-8-1 23:32 发表
貌似如果文件更多的话,单纯的ls也会有这样的问题

还是应该是shell解释的原因,比如超过了什么限制。


我也这么怀疑,验证了一下,确实是shell(bash)环境的问题, 参数过长的提示确实是bash报出来的 而非grep命令。
我在 rhel5 上(bash版本 3.1.17) 验证最多参数长度是 23534个。
在 fc 9 上 (bash版本 3.2.33) 最多参数长度在 39万到40万之间。
ls与此无关,它单纯是列出文件而已,没使用参数也与bash环境没有更多交互,只是文件多速度慢而已。

我的理解是:
xargs 把这些参数直接交给了调用的程序,而不再通过bash。当超出bash 限定的最大参数时,也不再检查。
至于能否接受这么多的参数,就看命令本身怎么实现了, grep pattern files[]  按我的理解(也是主观臆测) files[] 的长度应该是一个int类型的最大长度。即2^31个。

也感谢 eeef。

[ 本帖最后由 netcafe 于 2008-8-2 11:38 编辑 ]

论坛徽章:
0
20 [报告]
发表于 2008-09-27 21:30 |只看该作者

最新试验,证明xargs是根据它的最大饭量来决定分几次吃“参数”的。

输出 1 - 20000
$ seq 200000 | xargs echo "hoho" > abc.txt
打开 abc.txt  可以看到 hoho 只出现一次,文件共 1 行。

输出 100000 - 120000
$seq 100000 - 120000 | xargs echo "hoho" > cde.txt
打开 cde.txt 可以看到 hoho 出现了两次,文件共 2 行。

可以看出,xargs是根据输入的参数的“量”(数据量)决定要吃几次的:)


测试环境是 redhat as 5 xargs 4.2.27
2008-09-27
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP