我对
sitaram的回答,
Peter Cordes的评论,
Fanatique的回答和
harrymc的回答进行了基准测试,但
这个答案是最快的方法。
平均值:
Deltik的答案* - 7.480秒
* 感谢Peter Cordes提出并行性建议
sitaram的答案 - 12.962秒(比最佳答案慢73.275%)
Peter Cordes的评论 - 14.414秒(比最佳答案慢92.685%)
Fanatique的答案 - 14.570秒(比最佳答案慢94.772%)
harrymc的更新答案 - 14.791秒(比最佳答案慢97.730%)
harrymc的原始答案 - 1061.926秒(比最佳答案慢14096.113%)
完整的统计摘要:
Author N min q1 median q3 max mean stddev
------------------ -- ------- ------- ------- ------- ------- ------- --------
Deltik 10 7.121 7.3585 7.4615 7.558 8.005 7.4804 0.248965
sitaram 10 12.651 12.803 12.943 13.0685 13.586 12.9617 0.276589
Peter Cordes 10 14.096 14.2875 14.375 14.4495 15.101 14.4136 0.269732
Fanatique 10 14.219 14.512 14.5615 14.6525 14.892 14.5697 0.211788
harrymc (updated) 10 14.38 14.677 14.8595 14.9025 15.119 14.791 0.21817
harrymc (original) 1 1061.93 1061.93 1061.93 1061.93 1061.93 1061.93 N/A
Deltik的命令,以基准格式:
find "$(pwd)" -type d -print0 | xargs -0 -P4 chmod 755 & \
find "$(pwd)" -type f -print0 | xargs -0 -P4 chmod 644 & wait
sitaram的命令,以基准格式:
chmod -R a=,u+rwX,go+rX "$(pwd)"
Peter Cordes的命令,以基准格式:
find "$(pwd)" \( -type d -exec chmod 755 {} + \) \
-o \( -type f -exec chmod 644 {} + \)
Fanatique的命令,以基准格式:
find "$(pwd)" -type d -print0 | xargs -0 chmod 755 ; \
find "$(pwd)" -type f -print0 | xargs -0 chmod 644
harrymc的更新后的命令,以基准格式:
find "$(pwd)" -type d -exec chmod 755 {} + ; \
find "$(pwd)" -type f -exec chmod 644 {} +
harrymc的原始命令,以基准格式:
找到"$(pwd)" -type d -exec chmod 755 {} \; ; \
找到"$(pwd)" -type f -exec chmod 644 {} \;
我的命令是最快的,感谢每个文件类型中四个并行的chmod
进程。这样可以让多个CPU核心同时运行chmod
,将瓶颈转移到了内核I/O线程或磁盘上。
sitaram的命令是第二名,因为所有操作都在chmod
命令中完成。与其他答案相比,这大大减少了开销,因为:
- 文件只需要被扫描一次(类似于执行一次
find
而不是两次),并且
- 不需要创建子进程。
然而,这个命令的灵活性最差,因为它依赖于有关常规文件和目录之间可执行位含义的巧妙处理。
Peter Cordes的评论使用了一个find
命令,避免了目录条目的双重查找。文件越多,这种改进就越显著。它仍然需要创建子chmod
进程的开销,这就是为什么它比仅使用chmod
的解决方案慢得多的原因。
在Fanatique的命令和harrymc更新的命令之间,
find
管道传递到
xargs
(
find | xargs
)的速度更快,因为结果流是异步处理的。而不是
find
暂停其查找行为进行
-exec
,找到的结果被发送给
xargs
以进行并发处理。
(空字节分隔符(
find -print0 | xargs -0
)似乎不会影响运行时间。)
由于每个文件和文件夹都需要一个新的
chmod
命令的开销,并且按顺序执行,所以harrymc的原始命令速度太慢。
在测试设置中,有1001个目录中包含了1000002个常规文件:
root@demo:~# echo {0..999} | xargs mkdir -p
root@demo:~# find -type d -exec bash -c "cd {}; echo {0..999} | xargs touch" \;
root@demo:~# find | wc -l
1001003
root@demo:~# find -type d | wc -l
1001
root@demo:~# find -type f | wc -l
1000002
我将所有的文件和文件夹权限设置为777,就像问题的初始条件一样。
然后,我对命令进行了十次基准测试,每次在运行测试之前都使用chmod -R 0777 "$(pwd)"恢复权限为777。
使用OUTPUT表示包含每个基准测试命令输出的文件,我使用以下方法计算平均时间:
bc <<< "scale=3; ($(grep real OUTPUT | grep -Po '(?<=m).*(?=s)' | xargs | sed 's/ /+/g'))/10"
Deltik答案的基准测试结果
root@demo:~# for i in {0..9} ; do chmod -R 0777 "$(pwd)" ; time { find "$(pwd)" -type d -print0 | xargs -0 -P4 chmod 755 & find "$(pwd)" -type f -print0 | xargs -0 -P4 chmod 644 & wait ; } ; done
[1] 9791
[2] 9793
[1]- Done find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Done find "$(pwd)" -type f | xargs -P4 chmod 644
real 0m7.634s
user 0m2.536s
sys 0m23.384s
[1] 9906
[2] 9908
[1]- Done find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Done find "$(pwd)" -type f | xargs -P4 chmod 644
real 0m7.443s
user 0m2.636s
sys 0m23.106s
[1] 10021
[2] 10023
[1]- Done find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Done find "$(pwd)" -type f | xargs -P4 chmod 644
real 0m8.005s
user 0m2.672s
sys 0m24.557s
[1] 10136
[2] 10138
[1]- Done find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Done find "$(pwd)" -type f | xargs -P4 chmod 644
real 0m7.480s
user 0m2.541s
sys 0m23.699s
[1] 10251
[2] 10253
[1]- Done find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Done find "$(pwd)" -type f | xargs -P4 chmod 644
real 0m7.397s
user 0m2.558s
sys 0m23.583s
[1] 10366
[2] 10368
[1]- Done find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Done find "$(pwd)" -type f | xargs -P4 chmod 644
real 0m7.482s
user 0m2.601s
sys 0m23.728s
[1] 10481
[2] 10483
[1]- Done find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Done find "$(pwd)" -type f | xargs -P4 chmod 644
real 0m7.679s
user 0m2.749s
sys 0m23.395s
[1] 10596
[2] 10598
[1]- Done find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Done find "$(pwd)" -type f | xargs -P4 chmod 644
real 0m7.243s
user 0m2.583s
sys 0m23.400s
[1] 10729
[2] 10731
[1]- Done find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Done find "$(pwd)" -type f | xargs -P4 chmod 644
real 0m7.320s
user 0m2.640s
sys 0m23.403s
[1] 10844
[2] 10847
[1]- Done find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ Done find "$(pwd)" -type f | xargs -P4 chmod 644
real 0m7.121s
user 0m2.490s
sys 0m22.943s
平均时间:7.480秒
sitaram答案的基准测试结果
root@demo:~# for i in {0..9} ; do chmod -R 0777 "$(pwd)" ; time chmod -R a=,u+rwX,go+rX "$(pwd)" ; done
真实时间 0分12.860秒
用户时间 0分0.940秒
系统时间 0分11.725秒
真实时间 0分13.059秒
用户时间 0分0.896秒
系统时间 0分11.937秒
真实时间 0分12.819秒
用户时间 0分0.945秒
系统时间 0分11.706秒
真实时间 0分13.078秒
用户时间 0分0.855秒
系统时间 0分12.000秒
真实时间 0分12.653秒
用户时间 0分0.856秒
系统时间 0分11.667秒
真实时间 0分12.787秒
用户时间 0分0.820秒
系统时间 0分11.834秒
真实时间 0分12.651秒
用户时间 0分0.916秒
系统时间 0分11.578秒
真实时间 0分13.098秒
用户时间 0分0.939秒
系统时间 0分12.004秒
真实时间 0分13.586秒
用户时间 0分1.024秒
系统时间 0分12.372秒
真实时间 0分13.026秒
用户时间 0分0.976秒
系统时间 0分11.910秒
平均时间:12.962秒
Peter Cordes评论的基准结果
root@demo:~# for i in {0..9} ; do chmod -R 0777 "$(pwd)" ; time find "$(pwd)" \( -type d -exec chmod 755 {} + \) -o \( -type f -exec chmod 644 {} + \) ; done
real 0m14.096s
user 0m1.455s
sys 0m12.456s
real 0m14.492s
user 0m1.398s
sys 0m12.897s
real 0m14.309s
user 0m1.518s
sys 0m12.576s
real 0m14.451s
user 0m1.477s
sys 0m12.776s
real 0m15.101s
user 0m1.554s
sys 0m13.378s
real 0m14.223s
user 0m1.470s
sys 0m12.560s
real 0m14.266s
user 0m1.459s
sys 0m12.609s
real 0m14.357s
user 0m1.415s
sys 0m12.733s
real 0m14.393s
user 0m1.404s
sys 0m12.830s
real 0m14.448s
user 0m1.492s
sys 0m12.717s
平均时间:14.414秒
Fanatique回答的基准测试结果
root@demo:~# for i in {0..9} ; do chmod -R 0777 "$(pwd)" ; time { find "$(pwd)" -type d -print0 | xargs -0 chmod 755 ; find "$(pwd)" -type f -print0 | xargs -0 chmod 644 ; } ; done
real 0m14.561s
user 0m1.991s
sys 0m13.343s
real 0m14.521s
user 0m1.958s
sys 0m13.352s
real 0m14.696s
user 0m1.967s
sys 0m13.463s
real 0m14.562s
user 0m1.875s
sys 0m13.400s
real 0m14.609s
user 0m1.841s
sys 0m13.533s
real 0m14.892s
user 0m2.050s
sys 0m13.630s
real 0m14.291s
user 0m1.885s
sys 0m13.182s
real 0m14.843s
user 0m2.066s
sys 0m13.578s
real 0m14.219s
user 0m1.837s
sys 0m13.145s
real 0m14.503s
user 0m1.803s
sys 0m13.419s
平均时间:14.570秒
harrymc更新答案的基准测试结果
root@demo:~# for i in {0..9} ; do chmod -R 0777 "$(pwd)" ; time { find "$(pwd)" -type d -exec chmod 755 {} + ; find "$(pwd)" -type f -exec chmod 644 {} + ; } ; done
实际 0分14.975秒
用户 0分1.728秒
系统 0分13.050秒
实际 0分14.710秒
用户 0分1.586秒
系统 0分12.979秒
实际 0分14.644秒
用户 0分1.641秒
系统 0分12.872秒
实际 0分14.927秒
用户 0分1.706秒
系统 0分13.036秒
实际 0分14.867秒
用户 0分1.597秒
系统 0分13.086秒
实际 0分15.119秒
用户 0分1.666秒
系统 0分13.259秒
实际 0分14.878秒
用户 0分1.590秒
系统 0分13.098秒
实际 0分14.852秒
用户 0分1.681秒
系统 0分13.045秒
实际 0分14.380秒
用户 0分1.603秒
系统 0分12.663秒
实际 0分14.558秒
用户 0分1.514秒
系统 0分12.899秒
平均时间:14.791秒
harrymc原答案的基准测试结果
由于此命令非常缓慢,我只运行了一次基准测试。
root@demo:~# for i in {0..0} ; do chmod -R 0777 "$(pwd)" ; time { find "$(pwd)" -type d -exec chmod 755 {} \; ; find "$(pwd)" -type f -exec chmod 644 {} \; ; } ; done
real 17m41.926s
user 12m26.896s
sys 4m58.332s
耗时:1061.926秒