LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 898|回复: 11

xargs 的问题,请大虾赐教

[复制链接]
发表于 2006-5-15 14:47:25 | 显示全部楼层 |阅读模式
在精华贴"find和xargs祥解"里看到下面几句话:

下面的例子在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到
/tmp/core.log 文件中:
$ find . -name "core" -print | xargs echo "" >/tmp/core.log

echo "" >/tmp/core.log  就是把查找的结果传到指定的文件吗?? 不是很理解啊

那是两个双引号吗?? "" 就代表查找结果吗?? 请大虾指教啊
发表于 2006-5-15 16:16:05 | 显示全部楼层
这个命令完全可以简化成这样,就容易理解了:
find . -name "core" | xargs echo >/tmp/core.log
回复 支持 反对

使用道具 举报

发表于 2006-5-15 16:35:32 | 显示全部楼层
xargs默认的命令就是/bin/echo,加了个""的结果是多了个开头的空格,目的何在我也不知道。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-15 18:54:40 | 显示全部楼层
完成同样的功能,如果用这条语句也应该对吧??

find . -name "core"  -exec echo {} \; >/tmp/core.log

用{}代表查找到的结果。

还有一个小细节要问,就是语句中的 "\;"是什么意思?我不明白,请大虾指点

象seamonkey兄所说 ”xargs默认的命令就是/bin/echo“ 那么原来可以写成这样吗??

$ find . -name "core" -print | xargs  >/tmp/core.log
回复 支持 反对

使用道具 举报

发表于 2006-5-15 19:46:53 | 显示全部楼层
find . -name "core" -print | xargs >/tmp/core.log



find . -name "core" | xargs echo >/tmp/core.log


是一样的,更简明的是

find . -name "core" | xargs >/tmp/core.log

因为find的默认命令是print,xargs的默认命令是/bin/echo。

但和

find . -name "core" -print | xargs echo "" >/tmp/core.log

有区别。



find . -name "core" -exec echo {} \; >/tmp/core.log

更不一样,你可以看到在这里find pipe到xargs后输出的结果是文件名以空格分隔的一行,大概作者要的就是把这个效果。但我不清楚echo ""在行首加上一个空格是何意,另外文件名中有空格的话,那么这个`以空隔分隔的行'就没什么意思了,处理起来反而麻烦了。

xargs默认的分隔符是空隔和newline,所以文件名中如果有空格或者newline的话对于xargs就有麻烦了,一般来说

find print0 | xargs -0的配合才是绝对可靠的。但在这里,最终的输出没什么区别。

-exec和xargs的主要区别在于效率,find -exec command,每次对文件的处理重建一个command的进程,而pipe到xargs则一般情况下command只要执行一次,也就是一次性把从标准输出来的文件名送给command处理。

至于`\;',`\'是转义符,防止shell抢先对`;'解释,';'单引号的效果是一样的

  1.       -exec command ;
  2.               Execute command; true if 0 status is  returned.   All  following
  3.               arguments to find are taken to be arguments to the command until
  4.               an argument consisting of ‘;’ is encountered.  The  string  ‘{}’
  5.               is  replaced by the current file name being processed everywhere
  6.               it occurs in the arguments to the command, not just in arguments
  7.               where  it  is alone, as in some versions of find.  Both of these
  8.               constructions might need to be escaped (with a ‘\’) or quoted to
  9.               protect them from expansion by the shell.
复制代码


还是直接引用man吧,我觉得自己有些辞不达意了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-15 20:35:46 | 显示全部楼层
感谢了啊,哥们,刚才我也试过了,多谢了seamonkey 兄弟
回复 支持 反对

使用道具 举报

发表于 2006-5-15 21:22:48 | 显示全部楼层
我在一个有36个项目的目录下面分别执行

find . -maxdepth 1 -exec ls -ld {} \;

find . -maxdepth 1 -print0 | xargs -0 ls -ld

速度大不一样

怎么time一个pipeline,我突然有些不确定了,用/usr/bin/time,还是用shell keyword的time?
回复 支持 反对

使用道具 举报

发表于 2006-5-15 21:40:52 | 显示全部楼层
bash的time keyword应该是对整个pipeline计时的。

  1. time find . -maxdepth 1 -exec ls -ld {} \; >/dev/null

  2. real        0m2.071s
  3. user        0m1.216s
  4. sys        0m0.835s
复制代码

  1. time find . -maxdepth 1 -print0 | xargs -0 ls -ld >/dev/null

  2. real        0m0.053s
  3. user        0m0.027s
  4. sys        0m0.018s
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-5-15 21:46:18 | 显示全部楼层
Post by seamonkey
bash的time keyword应该是对整个pipeline计时的。

  1. time find . -maxdepth 1 -exec ls -ld {} \; >/dev/null

  2. real        0m2.071s
  3. user        0m1.216s
  4. sys        0m0.835s
复制代码

  1. time find . -maxdepth 1 -print0 | xargs -0 ls -ld >/dev/null

  2. real        0m0.053s
  3. user        0m0.027s
  4. sys        0m0.018s
复制代码


第二个有没有可能是因为已经运行了一次?
回复 支持 反对

使用道具 举报

发表于 2006-5-15 21:49:06 | 显示全部楼层
对于/usr/bin/time,下面这么做应该也是可行的,虽然要调用一个shell,但两相比较还是可以的。

  1. /usr/bin/time -p sh -c 'find . -maxdepth 1 -exec ls -ld {} \;' >/dev/null
  2. real 2.27
  3. user 1.25
  4. sys 0.84
复制代码

  1. /usr/bin/time -p sh -c 'find . -maxdepth 1 -print0 | xargs -0 ls -ld' >/dev/null
  2. real 0.06
  3. user 0.03
  4. sys 0.02
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表