find -exec 与 find - xargs 的差别

来源:互联网 发布:gedit ubuntu 编辑:程序博客网 时间:2024/05/17 20:31

最近我想统计下,家目录下各文件(夹)的硬盘占用情况,所以用了这个命令:
find -maxdepth 1 | xargs du -sh

返回的结果是,整个家目录的总大小,而不是预期的每个文件的大小。之后换用了find -maxdepth 1 -exec du -sh {} \;就能得出每个文件的大小。

为什么使用find | xargs得出的结果跟find -exec不一样呢?

一个问题是,我们为什么要使用xargs?xargs对find的标准输出做了什么处理?

以下面为例:

[lzx:~/.oh-my-zsh]¥ find -maxdepth 1 | xargs. ./plugins ./templates ./.git ./README.textile ./oh-my-zsh.sh ./log ./.gitignore ./custom ./cache ./MIT-LICENSE.txt ./themes ./tools ./lib[lzx:~/.oh-my-zsh]¥ find -maxdepth 1../plugins./templates./.git./README.textile./oh-my-zsh.sh./log./.gitignore./custom./cache./MIT-LICENSE.txt./themes./tools./lib

默认情况下,xargs只是把\n转换成了空格。

所以find -maxdepth 1 | xargs du -sh
近似于:du -sh . ./plugins ./templates ./.git ./README.textile ./oh-my-zsh.sh ./log ./.gitignore ./custom ./cache ./MIT-LICENSE.txt ./themes ./tools ./lib
结果是6.8M,而不是独立计算每个文件夹的硬盘占用。

有趣的是,如果移除所有条目前面的./,得出的结果就是

du -s cache custom lib log MIT-LICENSE.txt oh-my-zsh.sh plugins README.textile templates themes tools .git .924K cache20K custom72K lib8.0K log4.0K MIT-LICENSE.txt4.0K oh-my-zsh.sh2.0M plugins8.0K README.textile8.0K templates572K themes32K tools3.2M .git8.0K .

可见,使用find | xargsfind -exec之所以会得出不同的结果,du对命令行输入的处理方式也是原因之一。

再来看下find -exec是怎样的:
这里写了个argv.rb脚本,简单地输出命令行参数。

[lzx:~]¥ find ./code -exec ./argv.rb {} \;["./code"]["./code/test"]["./code/test/package.json"]["./code/test/public"]["./code/test/public/javascripts"]["./code/test/public/images"]["./code/test/public/stylesheets"]["./code/test/public/stylesheets/style.styl"]["./code/test/public/stylesheets/style.css"]["./code/test/views"]["./code/test/views/user.ejs"]["./code/test/views/index.ejs"]["./code/test/views/error.ejs"]["./code/test/models"]["./code/test/models/User.js"]...[lzx:~]¥ find ./code | xargs ./argv.rb["./code", "./code/test", "./code/test/package.json", "./code/test/public", "./code/test/public/javascripts", "./code/test/public/images", "./code/test/public/stylesheets", "./code/test/public/stylesheets/style.styl", "./code/test/public/stylesheets/style.css", "./code/test/views", "./code/test/views/user.ejs", "./code/test/views/index.ejs", "./code/test/views/error.ejs", "./code/test/models", "./code/test/models/User.js", ...]

可见find -exec是对每一个匹配的文件都执行了命令。

不过,如果不是以{} \;结尾({}会被替换成匹配的文件名),而是以{} +结尾,那么命令只会在最后执行一次。这类似于使用xargs的结果。

BTW,既然xargs只是简单地把\n变成空格,那么可能存在一些问题。比如文件名带空格,这时候xargs就给跪了。万一空格之后是-xx那样的内容,那就有得看了。当然通过指定\0作为分隔符,可以避免这种情况:

find . -maxdepth 1 -print0 | xargs -0 xxx

但是这么麻烦,还是坚持使用find . -exec xxx {} \;好了。

后记: 经别人指正,其实使用du -hd 1就能统计当前目录下各个文件(夹)占用的大小,无需使用find -maxdepth 1 -exec du -sh {} \;

0 0
原创粉丝点击