知了小巷:浪里淘沙,详解Linux系统中Find命令的实用技巧。
当我们需要在Linux系统上定位某个文件或目录时,find命令通常是必备之选。
它使用起来非常简单,但有许多不同的可选项,允许我们对要搜索的文件进行条件过滤。 下面的实例,将会展示如何使用find命令查找系统上的任何我们想要查找的内容。一旦我们知道如何在Linux中使用find命令,每个文件都只需要敲几下键盘就搞定了。
Linux 系统实验版本:
$ cat /proc/version
Linux version 3.10.0-957.1.3.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Thu Nov 29 14:49:43 UTC 2018
1. 查找目录
find命令后跟-type d选项,这将会使find只搜索目录而忽略文件。
$ find /path/to/search -type d -name "name-of-dir"
$ find / -type d -name 'home'
/home/admin/escheduler-ui/dist.old/css/home
/home/admin/escheduler-ui/dist.old/js/home
/home/admin/escheduler-ui/dist.20191112/css/home
/home/admin/escheduler-ui/dist.20191112/js/home
/home/admin/escheduler-ui/dist/css/home
/home/admin/escheduler-ui/dist/js/home
2. 查找隐藏文件
$ find /path/to/search -name ".*"
$ find ~/ -name ".*"
/home/admin/.trash/.py3_monitor_yarn_flinkjobs.py
/home/admin/.sqlline
/home/admin/.bash_profile
/home/admin/.ansible
3. 查找超过指定大小的文件
需要用到-size选项
查找超过10MB大小的文件:
$ find /path/to/search -size +10M
$ find ~/ -size +10M
/home/admin/hive.zip
/home/admin/flink-1.7.2.zip
查找小于10MB大小的文件:
$ find /path/to/search -size -10M
$ find ~/ -size -10M
/home/admin/tt.sh
/home/admin/ss.sh
/home/admin/send_email.py
查找刚刚好10MB大小的文件:
$ find /path/to/search -size 10M
$ find ~/ -size 10M
/home/admin/elk/elasticsearch-6.2.3/lib/elasticsearch-6.2.3.jar
查找介于100MB到2GB大小之间的文件:
$ find /path/to/search -size +100M -size -2G
$ find ~/ -size +100M -size -2G
/home/admin/streamsets-datacollector-3.11.0/libexec/bootstrap-libs/cluster/streamsets-datacollector-mesos-bootstrap-3.11.0.jar
4. 查找指定文件中文件名列表的一个或多个文件
需要用到管道符grep;查找结果是非精确文件名。
$ find /path/to/search | grep -f filelist.txt
$ echo tt.sh > shlist.txt
$ echo ss.sh >> shlist.txt
$ find ~/ | grep -f shlist.txt
/home/admin/elk/kibana-7.3.0-linux-x86_64/data/headless_shell-linux
/home/admin/elk/kibana-7.3.0-linux-x86_64/data/headless_shell-linux/headless_shell
/home/admin/tt.sh
/home/admin/ss.sh
需要注意的是文件名称中的“点”-. 会被忽略,下同:
$ echo 'tt.sh' > shlist2.txt
$ echo 'ss.sh' >> shlist2.txt
$ find ~/ | grep -f shlist2.txt
/home/admin/elk/kibana-7.3.0-linux-x86_64/data/headless_shell-linux
/home/admin/elk/kibana-7.3.0-linux-x86_64/data/headless_shell-linux/headless_shell
/home/admin/tt.sh
/home/admin/ss.sh
如果文件名称由单引号,会什么都找不到,单引号也是文件名称的一部分了:
$ echo "'tt.sh'" > shlist3.txt
$ echo "'ss.sh'" >> shlist3.txt
$ find ~/ | grep -f shlist3.txt
那怎样做才能精确找到与shlist.txt所列出的文件名称一模一样的文件呢???
答案是在文件名中的“点”前面加上转义字符"":
$ echo 'tt.sh' > shlist4.txt
$ echo 'ss.sh' >> shlist4.txt
$ find ~/ | grep -f shlist4.txt
/home/admin/tt.sh
/home/admin/ss.sh
5. 查找不在指定文件名列表范围内的文件
-v的意思是“inverse match“即反向匹配。
$ find /path/to/search | grep -vf filelist.txt
$ find ~/ | grep -vf shlist4.txt
/home/admin/shlist.txt
/home/admin/shlist3.txt
/home/admin/shlist2.txt
/home/admin/shlist4.txt
6. 设置查找的深度-maxdepth
find命令默认情况下会递归查找文件夹和子文件夹,所有子文件夹都会查找一遍。
我们可以使用-maxdepth选项来指定递归查找的文件夹层次数。
如果是当前文件夹下面,参数设置为0,如果是当前文件夹+子文件夹+子子文件夹,参数设置为2,以此类推。
$ find . -maxdepth 0 -name "myfile.txt"
$ find ~/ -maxdepth 2 -name "shlist.txt"
/home/admin/shlist.txt
7. 查找空文件
使用empty选项。
$ find /path/to/search -type f -empty
$ find ~/ -type f -empty
/home/admin/hive-2.3.5/examples/files/empty1.txt
/home/admin/hive-2.3.5/examples/files/empty2.txt
/home/admin/hive-2.3.5/examples/files/nullfile.txt
查找空文件夹:
$ find /path/to/search -type d -empty
$ find ~/ -type d -empty
/home/admin/nginx/srcnginx
/home/admin/.npm/_cacache/tmp
/home/admin/.npm/_locks
如果想要一次性删除空文件,可以使用-delete选项:
$ find /path/to/search -type f -empty -delete
8. 查找最大或比较大的文件夹或文件
$ find /path/to/search -type f -printf "%s%p" | sort -n | tail -1
$ find ~/ -type f -printf "%s%p" | sort -n | tail -1
1077105823 /home/admin/flink-1.7.2.zip
使用sort对文件的size进行排序,使用tail输出排在前面的n个文件。
文件输出的顺序,是从小到大。
如果要查找最小或topN小的文件,使用head就可以了:
$ find ~/ -type f -printf "%s%p" | sort -n | tail -5
268435627 /home/admin/hadoop-2.8.5/logs/hadoop-admin-namenode-testbi-flink-72.zlxx.local.log.6
268435631 /home/admin/hadoop-2.8.5/logs/hadoop-admin-namenode-testbi-flink-72.zlxx.local.log.3
284513057 /home/admin/elk/elasticsearch-7.3.0-linux-x86_64.tar.gz
301452104 /home/admin/test/flink-1.7.2-bin-hadoop28-scala_2.11.tgz
1077105823 /home/admin/flink-1.7.2.zip
查找最大的文件夹,未递归包括子文件夹下文件的大小:
$ find /path/to/search -type d -printf "%s%p" | sort -n | tail -1
$ find ~/ -type d -printf "%s%p" | sort -n | tail -1
344064 /home/admin/elk/kibana-7.3.0-linux-x86_64/built_assets/.cache/ui_bundles/babel
9. 查找普通用户能够使用root权限执行的文件
setuid:"set user ID on execution" ,普通用户能够使用root权限执行的文件。
SUID:SUID权限仅对二进制程序(binary program)有效;执行者对于该程序需要具有x的可执行权限;本权限仅在执行该程序的过程中有效(run-time);执行者将具有该程序拥有者(owner)的权限。
SUID的目的是:让本来没有相应权限的用户运行这个程序时,可以访问他没有权限访问的资源。
有两个选项:-user和-perm;-exec ls -l {} ;会输出更多信息。
# find /path/to/search -user root -perm /4000
# find / -user root -perm /4000
/usr/bin/mount
/usr/bin/su
/usr/bin/passwd
...
# find /path/to/search -user root -perm /4000 -exec ls -l {} ;
# find / -user root -perm /4000 -exec ls -l {} ;
-rwsr-xr-x 1 root root 44320 Oct 31 2018 /usr/bin/mount
-rwsr-xr-x 1 root root 32208 Oct 31 2018 /usr/bin/su
-rwsr-xr-x. 1 root root 27832 Jun 10 2014 /usr/bin/passwd
...
不指定用户:
$ find /path/to/search -perm /4000
10. 查找设置了SGID的文件
SGID:SGID对二进制程序有用;程序执行者对于该程序来说,需具备x的权限;SGID主要用在目录上。
和SUID一样,只是SGID是获得该程序所属用户组的权限。
例如:如果用户在此目录下具有w权限的话,若使用者在此目录下建立新文件,则新文件的群组与此目录的群组相同。
# find /path/to/search -perm /2000
# find / -perm /2000 -exec ls -l {} ;
-r-xr-sr-x. 1 root tty 15344 Jun 10 2014 /usr/bin/wall
-rwxr-sr-x 1 root tty 19624 Oct 31 2018 /usr/bin/write
---x--s--x 1 root nobody 382240 Apr 11 2018 /usr/bin/ssh-agent
...
设置了SUID或SGID的文件,结果看并不一定是同时满足:
# find /path/to/search -perm /6000
# find / -perm /6000 -exec ls -l {} ;
---s--x--x 1 root root 147392 Oct 31 2018 /usr/bin/sudo
-rwsr-xr-x 1 root root 44320 Oct 31 2018 /usr/bin/mount
-rwsr-xr-x 1 root root 32208 Oct 31 2018 /usr/bin/su
-rwsr-xr-x 1 root root 32048 Oct 31 2018 /usr/bin/umount
-rwxr-sr-x 1 root tty 19624 Oct 31 2018 /usr/bin/write
11. 查找文件输出的时候过滤掉"Permission denied"的文件
$ find / -name "myfile.txt" 2>%1 | grep -v "Permission denied"
# find / -name "ss.sh" 2>%1 | grep -v "Permission denied"
/home/admin/ss.sh
12. 查找最近一段时间内发生过变更的文件
-mtime选项指定一定天数。
最近30天:
$ find /path/to/search -type f -mtime -30
$ find ~/ -type f -mtime -30
/home/admin/.bash_history
/home/admin/flink-1.7.2/log/flink-admin-client-testbi-flink-72.zlxx.local.log
超过30天,就多啦:
$ find /path/to/search -type f -mtime +30
$ find ~/ -type f -mtime +30
/home/admin/.bash_profile
/home/admin/hive.zip
刚刚好30天,且输出更多文件信息:
$ find /path/to/search -type f -mtime 30
$ find ~/ -type f -mtime 30 -exec ls -l {} ;
-rw-rw-r-- 1 admin admin 2864754 Dec 9 16:51 /home/admin/apache-cassandra-3.0.18/logs/system.log
-rw-rw-r-- 1 admin admin 1841736 Dec 9 16:51 /home/admin/apache-cassandra-3.0.18/logs/gc.log.0.current
-rw-rw-r-- 1 admin admin 7550190 Dec 9 16:51 /home/admin/apache-cassandra-3.0.18/logs/debug.log
13. 根据文件变更时间进行排序
$ find /path/to/search -printf "%T+%p" | sort
$ find ~/ -type f -mtime 30 -printf "%T+%p" | sort
2019-12-09+16:51:04.9282457790 /home/admin/apache-cassandra-3.0.18/logs/system.log
2019-12-09+16:51:04.9392455540 /home/admin/apache-cassandra-3.0.18/logs/debug.log
2019-12-09+16:51:05.2652388850 /home/admin/apache-cassandra-3.0.18/logs/gc.log.0.current
默认是从小到达,也就是业界标准ASC,如果想要DESC:
$ find ~/ -type f -mtime 30 -printf "%T+%p" | sort -r
2019-12-09+16:51:05.2652388850 /home/admin/apache-cassandra-3.0.18/logs/gc.log.0.current
2019-12-09+16:51:04.9392455540 /home/admin/apache-cassandra-3.0.18/logs/debug.log
2019-12-09+16:51:04.9282457790 /home/admin/apache-cassandra-3.0.18/logs/system.log
14. find命令与locate命令的区别
默认情况下,Linux系统并没有locate命令:
$ locate ss.sh
-bash: locate: command not found
Linux locate命令用于查找符合条件的文档,他会去保存文档和目录名称的数据库内,查找合乎范本样式条件的文档或目录。
一般情况我们只需要输入 locate your_file_name 即可查找指定文件。
locate与find 不同: find 是去硬盘找,locate 只在/var/lib/slocate资料库中找。
locate的速度比find快,它并不是真的查找,而是查数据库,一般文件数据库在/var/lib/slocate/slocate.db中,所以locate的查找并不是实时的,而是以数据库的更新为准,一般是系统自己维护,也可以手工升级数据库 。
如果需要使用locate,可以进行以下操作:
# yum install mlocate -y
...
Installed:
mlocate.x86_64 0:0.26-8.el7
Complete!
# updatedb
$ locate ss.sh
/etc/profile.d/less.sh
/home/admin/ss.sh
类似like '%ss.sh'。
15. find命令执行时的CPU负载如何呢?
可以通过top命令监控find占用的资源情况,如果find的目录比较多比较深的时候。
使用ionice命令可以优化减少IO资源的使用:
$ ionice -c3 -n7 find /path/to/search -name "myfile.txt"
$ ionice -c3 -n7 find ~/ -type f -mtime 30 -printf "%T+%p" | sort -r
ionice: ignoring given class data for idle class
2019-12-09+16:51:05.2652388850 /home/admin/apache-cassandra-3.0.18/logs/gc.log.0.current
2019-12-09+16:51:04.9392455540 /home/admin/apache-cassandra-3.0.18/logs/debug.log
2019-12-09+16:51:04.9282457790 /home/admin/apache-cassandra-3.0.18/logs/system.log
使用nice命令可以优化减少CPU资源的使用:
$ nice -n 19 find /path/to/search -name "myfile.txt"
$ nice -n19 find ~/ -type f -mtime 30 -printf "%T+%p" | sort -r
2019-12-09+16:51:05.2652388850 /home/admin/apache-cassandra-3.0.18/logs/gc.log.0.current
2019-12-09+16:51:04.9392455540 /home/admin/apache-cassandra-3.0.18/logs/debug.log
2019-12-09+16:51:04.9282457790 /home/admin/apache-cassandra-3.0.18/logs/system.log
IO和CPU同时优化:
$ nice -n ionice -c2 -n7 find /path/to/search -name "myfile.txt"
【202001】