[20160425]find -exec command {} \+.txt
1.检查man find文档:
$ man find
....
-exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the
command until an argument consisting of ';' is encountered. The string '{}' is replaced by the current file
name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is
alone, as in some versions of find. Both of these constructions might need to be escaped (with a '\') or quoted
to protect them from expansion by the shell. See the EXAMPLES section for examples of the use of the '-exec'
option. The specified command is run once for each matched file. The command is executed in the starting
directory. There are unavoidable security problems surrounding use of the -exec option; you should use the
-execdir option instead.
-exec command {} +
This variant of the -exec option runs the specified command on the selected files, but the command line is
built by appending each selected file name at the end; the total number of invocations of the command will be
much less than the number of matched files. The command line is built in much the same way that xargs builds its
command lines. Only one instance of '{}' is allowed within the command. The command is executed in the starting
directory.
2.可以发现这种的不同.可以那我的测试环境来测试看看:
$ cd /u01/app/oracle/diag/rdbms/book/book/trace
$ ls -l book*|wc
9678 77424 742938
--有9678个book开头的文件.
$ time find . -type f -name book_\* -exec file {} \; >/dev/null
real 0m31.978s
user 0m8.896s
sys 0m20.040s
--需要31秒
$ time find . -type f -name book_\* -exec file {} \+ >/dev/null
real 0m2.713s
user 0m2.547s
sys 0m0.159s
--需要3秒
--两个执行方式不一样,前者相当于匹配一个执行1次.调用1次file命令.
--后者相当于匹配完成后执行,当然我这里文件不多能拼接在一行完成.
--实际上与xargs非常相似.
$ time find . -type f -name book_\* | xargs file >/dev/null
real 0m2.861s
user 0m2.699s
sys 0m0.177s
--从以上的测试可以看出使用+与xagrs相似,比;快许多!!
3.使用strace跟踪:
$ strace -c -f find . -type f -name book_\* -exec file {} \; >/dev/null
Process 14791 detached
Process 14792 attached
Process 2286 suspended
Process 2286 resumed
Process 14792 detached
Process 14793 attached
Process 2286 suspended
Process 2286 resumed
Process 14793 detached
Process 14794 attached
Process 2286 suspended
Process 2286 resumed
Process 14794 detached
Process 14795 attached
Process 2286 suspended
Process 2286 resumed
...太长,截断.
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
98.71 29.215553 2308 12656 wait4
0.62 0.183754 15 12656 clone
0.21 0.061274 0 468448 354399 open
0.15 0.045036 0 341779 278451 stat
0.07 0.021634 1 26516 munmap
0.05 0.015619 0 241685 mmap
0.05 0.013336 132 101 getdents
0.04 0.010725 0 38091 brk
0.04 0.010372 0 75943 mprotect
0.02 0.006682 0 75948 read
0.02 0.004560 0 25358 lstat
0.02 0.004509 0 114049 close
0.01 0.002380 0 101255 fstat
0.00 0.001032 0 12657 arch_prctl
0.00 0.000392 0 12656 write
0.00 0.000168 0 12658 12657 access
0.00 0.000138 0 12657 12656 ioctl
0.00 0.000000 0 1 rt_sigaction
0.00 0.000000 0 1 mremap
0.00 0.000000 0 75937 63280 execve
0.00 0.000000 0 1 uname
0.00 0.000000 0 45 fcntl
0.00 0.000000 0 12745 fchdir
------ ----------- ----------- --------- --------- ----------------
100.00 29.597164 1673843 721443 total
--注意errors列 execve=63280 ,
--63280/(75937-63280) = 4.999604961681
--继续使用strace 专门跟踪execve.
strace -e trace=execve -f find . -type f -name book_\* -exec file {} \; >/dev/null
Process 14991 suspended
[pid 15103] execve("./file", ["file", "./cdmp_20160413160831/book_smco_"], [/* 48 vars */]) = -1 ENOENT (No such file or directory)
[pid 15103] execve("./file", ["file", "./cdmp_20160413160831/book_smco_"], [/* 48 vars */]) = -1 ENOENT (No such file or directory)
[pid 15103] execve("/usr/kerberos/bin/file", ["file", "./cdmp_20160413160831/book_smco_"], [/* 48 vars */]) = -1 ENOENT (No such file or directory)
[pid 15103] execve("/usr/local/bin/file", ["file", "./cdmp_20160413160831/book_smco_"], [/* 48 vars */]) = -1 ENOENT (No such file or directory)
[pid 15103] execve("/bin/file", ["file", "./cdmp_20160413160831/book_smco_"], [/* 48 vars */]) = -1 ENOENT (No such file or directory)
[pid 15103] execve("/usr/bin/file", ["file", "./cdmp_20160413160831/book_smco_"], [/* 48 vars */]) = 0
Process 14991 resumed
--可以发现一个问题,检索file命令安装环境变量PATH来检索.从这里也看出优先使用的命令放在前面可以加快执行.
$ echo $PATH
.:.:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/NX/bin:/home/oracle/bin:/home/oracle/bin:/u01/app/oracle/product/11.2.0.4/dbhome_1/bin:/home/oracle/anysql:/usr/NX/bin:/home/oracle/bin:/home/oracle/bin:/u01/app/oracle/product/11.2.0.4/dbhome_1/bin:/home/oracle/anysql
--我同事设置有问题,不应该将当前目录放在PATH环境变量中.
$ strace -c -f find . -type f -name book_\* -exec file {} \+ >/dev/null
Process 15118 attached
Process 15117 suspended
Process 15117 resumed
Process 15118 detached
Process 15119 attached
Process 15117 suspended
Process 15117 resumed
Process 15119 detached
Process 15120 attached
Process 15117 suspended
Process 15117 resumed
Process 15120 detached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
97.29 0.632905 210968 3 wait4
2.03 0.013197 131 101 getdents
0.42 0.002761 0 25358 lstat
0.11 0.000696 0 12940 115 open
0.09 0.000559 0 12683 read
0.04 0.000291 0 12825 close
0.01 0.000085 1 101 brk
0.00 0.000032 0 92 fchdir
0.00 0.000017 0 148 85 stat
0.00 0.000000 0 203 write
0.00 0.000000 0 31 fstat
0.00 0.000000 0 88 mmap
0.00 0.000000 0 25 mprotect
0.00 0.000000 0 20 munmap
0.00 0.000000 0 1 rt_sigaction
0.00 0.000000 0 4 3 ioctl
0.00 0.000000 0 5 4 access
0.00 0.000000 0 1 mremap
0.00 0.000000 0 3 clone
0.00 0.000000 0 19 15 execve
0.00 0.000000 0 1 uname
0.00 0.000000 0 45 fcntl
0.00 0.000000 0 4 arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00 0.650543 64701 222 total
$ strace -e trace=execve -f find . -type f -name book_\* -exec file {} \+ >/dev/null
execve("/usr/bin/find", ["find", ".", "-type", "f", "-name", "book_*", "-exec", "file", "{}", "+"], [/* 48 vars */]) = 0
Process 28687 attached
Process 28686 suspended
[pid 28687] execve("/usr/bin/file", ["file", "./book_j000_16141.trm", "./book_m000_23747.trm", "./book_vktm_37811.trm", "./book_pr08_7701.trc", "./book_m001_9257.trm", "./book_m000_31018.trc", "./book_dbrm_28164.trm", "./book_pr08_34999.trm", "./book_mman_28046.trc", "./book_pr0d_34205.trm", "./book_m001_34665.trm", "./book_diag_37811_20160329151621", "./book_m000_34175.trc", "./book_vktm_39878.trm", "./book_pr03_34615.trc", ...], [/* 48 vars */]) = 0
Process 28686 resumed
Process 28687 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
Process 28688 attached
Process 28686 suspended
[pid 28688] execve("/usr/bin/file", ["file", "./book_ora_38927.trc", "./book_m000_21235.trm", "./book_pr0l_52078.trm", "./book_pr0f_55348.trm", "./book_ora_37710.trm", "./book_pr06_55330.trc", "./book_ora_59046.trc", "./book_ora_38654.trm", "./book_pr08_3929.trm", "./book_m000_29866.trm", "./book_ora_52818.trm", "./book_mman_24785.trm", "./book_m000_11860.trm", "./book_pr06_55330.trm", "./book_m001_26669.trc", ...], [/* 48 vars */]) = 0
Process 28686 resumed
Process 28688 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
Process 28689 attached
Process 28686 suspended
[pid 28689] execve("/usr/bin/file", ["file", "./book_m000_7520.trc", "./book_p008_25487.trm", "./book_pr05_33648.trc", "./book_fbda_21614.trc", "./book_dbrm_33862.trc", "./book_pr00_54088.trc", "./book_ora_44078.trc", "./book_m001_8890.trm", "./book_vktm_63231.trm", "./book_pr02_34471.trm", "./book_p015_25378.trc", "./book_pr06_33924.trm", "./book_pr0f_4098.trm", "./book_diag_27324.trm", "./book_cjq0_39498.trm", ...], [/* 48 vars */]) = 0
Process 28686 resumed
Process 28689 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
--从这里可以看出匹配一定数量后开始执行.这样调用file测试明显减少.
--看来以后要习惯使用+来代替;