本帖最后由 alyssa 于 2023-10-29 16:09 编辑
Linux应急响应中,find命令是用的最多的一个命令。分享一些鲜为人知的find命令排查技巧,熟练运用可以达到事半功倍的效果find使用广度优先遍历查找文件find命令默认是深度优先遍历,并且不支持广度优先遍历。 应急最头疼的点就在于,需要排查某些文件中的关键字,但是深度优先遍历使得find命令在某些很深的目录中做无用功,而且要搜索完才能进入到下一个一级目录,总是浪费大量时间。 有什么办法使得find支持广度优先遍历呢? 巧妙利用find命令的depth参数find命令是支持查找目录的层级,比如 -mindepth 和 -maxdepth 参数,分别对应查找最少和最多的目录层级。 - seq 1 10 | xargs -n2 -P5 sh -c 'find / -iname "xxx" -mindepth $1 -maxdepth $2 2>/dev/null' _
该命令相当于find查找指定层级的目录,比如第一次是在1-2层目录中查找,第二次在3-4层目录中匹配。上面的命令看起来会有点抽象,换成下面这种就好理解了。 [root@VM-4-7-centos ~]# seq 1 10 | xargs-n2 1 2 3 4 5 6 7 8 9 10 [root@VM-4-7-centos ~]# seq 1 10 | xargs-n2 sh -c 'echo find / -iname xxx -mindepth $1 -maxdepth $2 2>/dev/null' _ find / -iname xxx -mindepth 1 -maxdepth 2 find / -iname xxx -mindepth 3 -maxdepth 4 find / -iname xxx -mindepth 5 -maxdepth 6 find / -iname xxx -mindepth 7 -maxdepth 8 find / -iname xxx -mindepth 9 -maxdepth 10
xargs -P5 的是指 5个子进程同时执行,可提升查找速度。 seq 1 10 表示最多查找10层目录,可根据自身需要修改。 配合grep查找文件内关键字- seq 1 10 | xargs -n2 -P5 sh -c 'find / -type f -mindepth $1 -maxdepth $2 -exec grep -inl "keyword" {} 2>/dev/null \;' _
匹配成功后不会直接匹配的内容,而是打印文件的路径。对于不清楚特定关键字位于哪个文件时,该命令排查非常高效。 find查找指定时间段内变动的文件这也是我在排查中用的最多的一个选项。有时需要定位某一个时间段内的文件变动就需要用到 -newermt 选项。格式如下: find / -newermt “开始时间” ! -newermt “截止时间” 注意中间的感叹号不能省略。 比如我要查找 2022年12月31日23:00 到 2023年1月1日1:00 期间发生变动的文件,条件看起来比较苛刻,但 -newermt 可以完全满足。命令如下: - find / -newermt "2022-12-31 23:00" ! -newermt "2023-01-01 01:00" 2>/dev/null
或者还可以输出文件的修改时间。 - find / -newermt "2022-12-31 23:00" ! -newermt "2023-01-01 01:00" -exec ls -lh {} \; 2>/dev/null
查找过去n天的文件变动比如查找过去3天内的文件变动,命令如下: 如果先查找3天前的文件变动则是: - find / -type f -mtime +3find查找特定权限的文件查找可执行文件
- find /root -executable -type f -exec ls -lh {} \; -quit
-executable 指定可执行权限的文件 -quit 匹配到第一个符合条件的文件就退出
查找带s位的文件- find / \( -perm -4000 -o -perm -2000 \) -type f -exec ls -lh {} \; 2>/dev/null
为什么是-perm -4000 而不是-perm 4000,有何区别? 在 find 命令中使用 -perm 选项时,- 前缀有特殊的含义。-perm -mode 会匹配任何文件的权限中设置了任何 mode 指定的位的文件,而 perm mode 只会匹配文件权限完全等于 mode 的文件。 例如,-perm -4000 会匹配所有设置了 setuid 位的文件(不考虑其他权限位是什么),而 -perm 4000 会匹配文件权限完全为 4000(即只有 setuid 位被设置,其他所有权限位都没有被设置)的文件。 查找指定权限的文件比如要查找系统中0700权限的文件,这里和上面的例子恰好相反,是完全匹配。 - find / -perm 0700 -type f -exec ls -lh {} \; 2>/dev/null
find 目录取反应急排查中,往往需要排除掉部分指定的目录。比如查找根目录下的所有可执行文件,但排除/usr目录。 - find / -path /usr -prune -o -type f -executable
在这个命令中,-path /usr -prune -o 表示如果路径是 /usr,则不搜索该路径,否则继续执行后面的命令。 ]如果要排除多个目录呢? - find / \( -path /usr -o -path /etc \) -prune -o -executable
这时候就需要括号把多个目录放在一起进行过滤。 find 并行操作以使用 + 代替 \; 来在 find 命令中执行并行操作。 比如排查完成之后需要把一些不同层级目录下的文件,统一打包回传。例如把 /targetDir 下面所有的可执行进行打包并压缩。 - find /targetDir -type f -executable -exec tar -rvf executables.tar {} +
- gzip executables.tar
或者首先找到所有的文件,然后一次性将它们添加到 tar 存档中。这样你就可以将存档压缩,而无需追加文件。注意-print0 和 -0 选项是用来处理文件名中可能包含的特殊字符(如空格或换行符)的。 - find . -type f -executable -print0 | xargs -0 tar -czvf executables.tgz
但这种方式没有用到find的并行。 再举一个例子,要在一个目录中查找所有 .jpg 文件并将它们复制到另一个目录,命令如下: - find /path/to/dir -name "*.jpg" -exec cp {} /path/to/other/dir +
这将使用尽可能多的参数来调用 cp,而不是每找到一个文件就调用一次 cp。 find中 exec 的 + 和 \; 的区别?在 find 命令的 -exec 操作后面,可以用 \; 或 + 结束。 + 的方式通常更为高效,因为它减少了需要执行的命令的次数。然而,并非所有的命令都能接受多个文件作为参数,对于这种情况就需要使用 \; 的方式。 find 正则表达式搜索-regex 选项可以使用正则表达式进行搜索,而不仅仅是简单的文件名匹配。例如要查找png或者jpg结尾的文件。 - find / -regex ".*\.\(jpg\|png\)$"
会同时找到所有的 .jpg 和 .png 文件,满足更复杂的查找需求。 作者:Zgao
来源:Zgao's blog,见阅读原文
|