檔案檔名的搜尋

以下摘自鸟哥的linux私房菜

談一談怎麼搜尋檔案吧!在 Linux 底下也有相當優異的搜尋指令呦!通常 find 不很常用的!因為速度慢之外, 也很操硬碟!一般我們都是先使用 whereis 或者是 locate 來檢查,如果真的找不到了,才以 find 來搜尋呦! 為什麼呢?因為 whereis 只找系統中某些特定目錄底下的檔案而已,locate 則是利用資料庫來搜尋檔名,當然兩者就相當的快速, 並且沒有實際的搜尋硬碟內的檔案系統狀態,比較省時間啦!

  • whereis (由一些特定的目錄中尋找檔案檔名)
[root@study ~]# whereis [-bmsu] 檔案或目錄名
選項與參數:
-l    :可以列出 whereis 會去查詢的幾個主要目錄而已
-b    :只找 binary 格式的檔案
-m    :只找在說明檔 manual 路徑下的檔案
-s    :只找 source 來源檔案
-u    :搜尋不在上述三個項目當中的其他特殊檔案

範例一:請找出 ifconfig 這個檔名
[root@study ~]# whereis ifconfig 
ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz

範例二:只找出跟 passwd 有關的『說明文件』檔名(man page)
[root@study ~]# whereis passwd     # 全部的檔名通通列出來!
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz
[root@study ~]# whereis -m passwd  # 只有在 man 裡面的檔名才抓出來!
passwd: /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz

等一下我們會提到 find 這個搜尋指令, find 是很強大的搜尋指令,但時間花用的很大!(因為 find 是直接搜尋硬碟,為如果你的硬碟比較老舊的話,嘿嘿!有的等!) 這個時候 whereis 就相當的好用了!另外, whereis 可以加入選項來找尋相關的資料,例如,如果你是要找可執行檔 (binary) 那麼加上 -b 就可以啦! 如果不加任何選項的話,那麼就將所有的資料列出來囉!

那麼 whereis 到底是使用什麼咚咚呢?為何搜尋的速度會比 find 快這麼多? 其實那也沒有什麼,只是因為 whereis 只找幾個特定的目錄而已~並沒有全系統去查詢之故。所以說,whereis 主要是針對 /bin /sbin 底下的執行檔, 以及 /usr/share/man 底下的 man page 檔案,跟幾個比較特定的目錄來處理而已。所以速度當然快的多!不過,就有某些檔案是你找不到的啦! 想要知道 whereis 到底查了多少目錄?可以使用 whereis -l 來確認一下即可!

  • locate / updatedb
[root@study ~]# locate [-ir] keyword
選項與參數:
-i  :忽略大小寫的差異;
-c  :不輸出檔名,僅計算找到的檔案數量
-l  :僅輸出幾行的意思,例如輸出五行則是 -l 5
-S  :輸出 locate 所使用的資料庫檔案的相關資訊,包括該資料庫紀錄的檔案/目錄數量等
-r  :後面可接正規表示法的顯示方式

範例一:找出系統中所有與 passwd 相關的檔名,且只列出 5 個
[root@study ~]# locate -l 5 passwd
/etc/passwd
/etc/passwd-
/etc/pam.d/passwd
/etc/security/opasswd
/usr/bin/gpasswd

範例二:列出 locate 查詢所使用的資料庫檔案之檔名與各資料數量
[root@study ~]# locate -S
Database /var/lib/mlocate/mlocate.db:
        8,086 directories     # 總紀錄目錄數
        109,605 files         # 總紀錄檔案數
        5,190,295 bytes in file names
        2,349,150 bytes used to store database

這個 locate 的使用更簡單,直接在後面輸入『檔案的部分名稱』後,就能夠得到結果。 舉上面的例子來說,我輸入 locate passwd ,那麼在完整檔名 (包含路徑名稱) 當中,只要有 passwd 在其中, 就會被顯示出來的!這也是個很方便好用的指令,如果你忘記某個檔案的完整檔名時~~

但是,這個東西還是有使用上的限制呦!為什麼呢?你會發現使用 locate 來尋找資料的時候特別的快, 這是因為 locate 尋找的資料是由『已建立的資料庫 /var/lib/mlocate/』 裡面的資料所搜尋到的,所以不用直接在去硬碟當中存取資料,呵呵!當然是很快速囉!

那麼有什麼限制呢?就是因為他是經由資料庫來搜尋的,而資料庫的建立預設是在每天執行一次 (每個 distribution 都不同,CentOS 7.x 是每天更新資料庫一次!),所以當你新建立起來的檔案, 卻還在資料庫更新之前搜尋該檔案,那麼 locate 會告訴你『找不到!』呵呵!因為必須要更新資料庫呀!

那能否手動更新資料庫哪?當然可以啊!更新 locate 資料庫的方法非常簡單,直接輸入『 updatedb 』就可以了! updatedb 指令會去讀取 /etc/updatedb.conf 這個設定檔的設定,然後再去硬碟裡面進行搜尋檔名的動作, 最後就更新整個資料庫檔案囉!因為 updatedb 會去搜尋硬碟,所以當你執行 updatedb 時,可能會等待數分鐘的時間喔!

  • updatedb:根據 /etc/updatedb.conf 的設定去搜尋系統硬碟內的檔名,並更新 /var/lib/mlocate 內的資料庫檔案;
  • locate:依據 /var/lib/mlocate 內的資料庫記載,找出使用者輸入的關鍵字檔名。
  • find
[root@study ~]# find [PATH] [option] [action]
選項與參數:
1. 與時間有關的選項:共有 -atime, -ctime 與 -mtime ,以 -mtime 說明
   -mtime  n :n 為數字,意義為在 n 天之前的『一天之內』被更動過內容的檔案;
   -mtime +n :列出在 n 天之前(不含 n 天本身)被更動過內容的檔案檔名;
   -mtime -n :列出在 n 天之內(含 n 天本身)被更動過內容的檔案檔名。
   -newer file :file 為一個存在的檔案,列出比 file 還要新的檔案檔名

範例一:將過去系統上面 24 小時內有更動過內容 (mtime) 的檔案列出
[root@study ~]# find / -mtime 0
# 那個 0 是重點!0 代表目前的時間,所以,從現在開始到 24 小時前,
# 有變動過內容的檔案都會被列出來!那如果是三天前的 24 小時內?
# find / -mtime 3 有變動過的檔案都被列出的意思!

範例二:尋找 /etc 底下的檔案,如果檔案日期比 /etc/passwd 新就列出
[root@study ~]# find /etc -newer /etc/passwd
# -newer 用在分辨兩個檔案之間的新舊關係是很有用的!

時間參數真是挺有意思的!我們現在知道 atime, ctime 與 mtime 的意義,如果你想要找出一天內被更動過的檔案名稱, 可以使用上述範例一的作法。但如果我想要找出『4天內被更動過的檔案檔名』呢?那可以使用『 find /var -mtime -4 』。那如果是『4天前的那一天』就用『 find /var -mtime 4 』。有沒有加上『+, -』差別很大喔!我們可以用簡單的圖示來說明一下:

find 相關的時間參數意義
圖6.5.1、find 相關的時間參數意義

圖中最右邊為目前的時間,越往左邊則代表越早之前的時間軸啦。由圖 6.5.1 我們可以清楚的知道:

  • +4代表大於等於5天前的檔名:ex> find /var -mtime +4
  • -4代表小於等於4天內的檔案檔名:ex> find /var -mtime -4
  • 4則是代表4-5那一天的檔案檔名:ex> find /var -mtime 4

非常有趣吧!你可以在 /var/ 目錄下搜尋一下,感受一下輸出檔案的差異喔!再來看看其他 find 的用法吧!

選項與參數:
2. 與使用者或群組名稱有關的參數:
   -uid n :n 為數字,這個數字是使用者的帳號 ID,亦即 UID ,這個 UID 是記錄在
            /etc/passwd 裡面與帳號名稱對應的數字。這方面我們會在第四篇介紹。
   -gid n :n 為數字,這個數字是群組名稱的 ID,亦即 GID,這個 GID 記錄在
            /etc/group,相關的介紹我們會第四篇說明~
   -user name :name 為使用者帳號名稱喔!例如 dmtsai 
   -group name:name 為群組名稱喔,例如 users ;
   -nouser    :尋找檔案的擁有者不存在 /etc/passwd 的人!
   -nogroup   :尋找檔案的擁有群組不存在於 /etc/group 的檔案!
                當你自行安裝軟體時,很可能該軟體的屬性當中並沒有檔案擁有者,
                這是可能的!在這個時候,就可以使用 -nouser 與 -nogroup 搜尋。

範例三:搜尋 /home 底下屬於 dmtsai 的檔案
[root@study ~]# find /home -user dmtsai
# 這個東西也很有用的~當我們要找出任何一個使用者在系統當中的所有檔案時,
# 就可以利用這個指令將屬於某個使用者的所有檔案都找出來喔!

範例四:搜尋系統中不屬於任何人的檔案
[root@study ~]# find / -nouser
# 透過這個指令,可以輕易的就找出那些不太正常的檔案。如果有找到不屬於系統任何人的檔案時,
# 不要太緊張,那有時候是正常的~尤其是你曾經以原始碼自行編譯軟體時。

如果你想要找出某個使用者在系統底下建立了啥咚咚,使用上述的選項與參數,就能夠找出來啦! 至於那個 -nouser 或 -nogroup 的選項功能中,除了你自行由網路上面下載檔案時會發生之外, 如果你將系統裡面某個帳號刪除了,但是該帳號已經在系統內建立很多檔案時,就可能會發生無主孤魂的檔案存在! 此時你就得使用這個 -nouser 來找出該類型的檔案囉!

選項與參數:
3. 與檔案權限及名稱有關的參數:
   -name filename:搜尋檔案名稱為 filename 的檔案;
   -size [+-]SIZE:搜尋比 SIZE 還要大(+)或小(-)的檔案。這個 SIZE 的規格有:
                   c: 代表 byte, k: 代表 1024bytes。所以,要找比 50KB
                   還要大的檔案,就是『 -size +50k 』
   -type TYPE    :搜尋檔案的類型為 TYPE 的,類型主要有:一般正規檔案 (f), 裝置檔案 (b, c),
                   目錄 (d), 連結檔 (l), socket (s), 及 FIFO (p) 等屬性。
   -perm mode  :搜尋檔案權限『剛好等於』 mode 的檔案,這個 mode 為類似 chmod
                 的屬性值,舉例來說, -rwsr-xr-x 的屬性為 4755 !
   -perm -mode :搜尋檔案權限『必須要全部囊括 mode 的權限』的檔案,舉例來說,
                 我們要搜尋 -rwxr--r-- ,亦即 0744 的檔案,使用 -perm -0744,
                 當一個檔案的權限為 -rwsr-xr-x ,亦即 4755 時,也會被列出來,
                 因為 -rwsr-xr-x 的屬性已經囊括了 -rwxr--r-- 的屬性了。
   -perm /mode :搜尋檔案權限『包含任一 mode 的權限』的檔案,舉例來說,我們搜尋
                 -rwxr-xr-x ,亦即 -perm /755 時,但一個檔案屬性為 -rw-------
                 也會被列出來,因為他有 -rw.... 的屬性存在!

範例五:找出檔名為 passwd 這個檔案
[root@study ~]# find / -name passwd

範例五-1:找出檔名包含了 passwd 這個關鍵字的檔案
[root@study ~]# find / -name "*passwd*"
# 利用這個 -name 可以搜尋檔名啊!預設是完整檔名,如果想要找關鍵字,
# 可以使用類似 * 的任意字元來處理

範例六:找出 /run 目錄下,檔案類型為 Socket 的檔名有哪些?
[root@study ~]# find /run -type s
# 這個 -type 的屬性也很有幫助喔!尤其是要找出那些怪異的檔案,
# 例如 socket 與 FIFO 檔案,可以用 find /run -type p 或 -type s 來找!

範例七:搜尋檔案當中含有 SGID 或 SUID 或 SBIT 的屬性
[root@study ~]# find / -perm /7000 
# 所謂的 7000 就是 ---s--s--t ,那麼只要含有 s 或 t 的就列出,所以當然要使用 /7000,
# 使用 -7000 表示要同時含有 ---s--s--t 的所有三個權限。而只需要任意一個,就是 /7000 ~瞭乎?

上述範例中比較有趣的就屬 -perm 這個選項啦!他的重點在找出特殊權限的檔案囉! 我們知道 SUID 與 SGID 都可以設定在二進位程式上,假設我想要找出來 /usr/bin, /usr/sbin 這兩個目錄下, 只要具有 SUID 或 SGID 就列出來該檔案,你可以這樣做:

[root@study ~]# find /usr/bin /usr/sbin -perm /6000

因為 SUID 是 4 分,SGID 2 分,總共為 6 分,因此可用 /6000 來處理這個權限! 至於 find 後面可以接多個目錄來進行搜尋!另外, find 本來就會搜尋次目錄,這個特色也要特別注意喔! 最後,我們再來看一下 find 還有什麼特殊功能吧!

選項與參數:
4. 額外可進行的動作:
   -exec command :command 為其他指令,-exec 後面可再接額外的指令來處理搜尋到的結果。
   -print        :將結果列印到螢幕上,這個動作是預設動作!

範例八:將上個範例找到的檔案使用 ls -l 列出來~
[root@study ~]# find /usr/bin /usr/sbin -perm /7000 -exec ls -l {} ;
# 注意到,那個 -exec 後面的 ls -l 就是額外的指令,指令不支援命令別名,
# 所以僅能使用 ls -l 不可以使用 ll 喔!注意注意!

範例九:找出系統中,大於 1MB 的檔案
[root@study ~]# find / -size +1M

find 的特殊功能就是能夠進行額外的動作(action)。我們將範例八的例子以圖解來說明如下:

find 相關的額外動作
圖6.5.2、find 相關的額外動作

該範例中特殊的地方有 {} 以及 ; 還有 -exec 這個關鍵字,這些東西的意義為:

  • {} 代表的是『由 find 找到的內容』,如上圖所示,find 的結果會被放置到 {} 位置中;
  • -exec 一直到 ; 是關鍵字,代表 find 額外動作的開始 (-exec) 到結束 (;) ,在這中間的就是 find 指令內的額外動作。 在本例中就是『 ls -l {} 』囉!
  • 因為『 ; 』在 bash 環境下是有特殊意義的,因此利用反斜線來跳脫。

透過圖 6.5.2 你應該就比較容易瞭解 -exec 到 ; 之間的意義了吧!

如果你要找的檔案是具有特殊屬性的,例如 SUID 、檔案擁有者、檔案大小等等, 那麼利用 locate 是沒有辦法達成你的搜尋的!此時 find 就顯的很重要啦! 另外,find 還可以利用萬用字元來找尋檔名呢!舉例來說,你想要找出 /etc 底下檔名包含 httpd 的檔案, 那麼你就可以這樣做:

[root@study ~]# find /etc -name '*httpd*'

不但可以指定搜尋的目錄(連同次目錄),並且可以利用額外的選項與參數來找到最正確的檔名!真是好好用! 不過由於 find 在尋找資料的時後相當的操硬碟!所以沒事情不要使用 find 啦!有更棒的指令可以取代呦!那就是上面提到的 whereis 與 locate 囉!

原文地址:https://www.cnblogs.com/taosiyu/p/12973841.html