如何优化含多个-o逻辑或的GNU find命令?
优化SlackBuild中批量修改权限的find命令
你的问题核心在于原命令和尝试的parallel方案都存在进程启动开销大或重复遍历目录的问题,以下是几种更高效的优化方式:
最基础的优化:用-exec {} +替代-exec {} \;
原命令里-exec chmod {} \;会为每个匹配到的文件单独启动一个chmod进程,文件数量极多时,进程启动的开销会被大幅放大。改用-exec {} +后,find会把尽可能多的文件路径一次性传给同一个chmod进程,直接减少进程启动次数:
find -L . \ \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 -o -perm 511 \) -exec chmod 755 {} + -o \ \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) -exec chmod 644 {} +
进阶优化:简化权限匹配规则+单次遍历目录
你原命令的逻辑本质是:给所有带执行权限的文件/目录设755,给无执行权限的普通文件设644。Slackware默认用GNU工具链,GNU find支持-perm /111语法,可直接匹配任何拥有至少一个执行位(用户/组/其他)的文件,不用罗列一堆权限值,同时只遍历目录一次:
find -L . \ \( -perm /111 -exec chmod 755 {} + \) -o \ \( ! -perm /111 -exec chmod 644 {} + \)
这个命令的优势:
- 权限匹配逻辑更简洁,find内部处理更快
- 仅遍历目录一次,避免两次find的重复IO开销
- 批量传递文件给chmod,彻底消除进程启动的额外消耗
关于GNU Parallel无效的原因
你之前用Parallel没效果,核心原因是:
- 分两次执行find,重复遍历目录,浪费IO资源
- chmod是IO密集型操作,多进程并行反而会引发磁盘寻道竞争,抵消并行收益
- 未加
-X参数的Parallel会为每个文件启动一个chmod进程,反而加重进程开销
如果一定要用Parallel,建议结合-X批量传参,同时减少遍历次数:
# 一次find遍历完成两类文件的权限修改 find -L . -print0 | parallel -0 -X \ 'if [ -x {} ]; then chmod 755 {}; else chmod 644 {}; fi'
不过实际测试下来,这种方式的效率依然不如前面单次find+批量exec的方案。
内容的提问来源于stack exchange,提问作者Geremia
相关产品推荐
相关产品推荐

