知了小巷:浪里淘沙,詳解Linux系統中Find命令的實用技巧。

啊哈,找到了!
當我們需要在Linux系統上定位某個文件或目錄時,find命令通常是必備之選。
它使用起來非常簡單,但有許多不同的可選項,允許我們對要搜索的文件進行條件過濾。 下面的實例,將會展示如何使用find命令查找系統上的任何我們想要查找的內容。一旦我們知道如何在Linux中使用find命令,每個文件都只需要敲幾下鍵盤就搞定了。

finding...
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】

end