1. 程式人生 > >linux每日命令(22): find命令引數詳解

linux每日命令(22): find命令引數詳解

閱讀目錄(Content)

  • 一. name選項
  • 二. perm選項
  • 三. prune選項(此處引用http://blog.sina.com.cn/s/blog_6ad648f30100tqwy.html)
    • 1.查詢檔案時,忽略某個目錄
    • 2. 忽略多個資料夾
  • 四. user和nouser 選項
    • 1. 在$HOME目錄中查詢檔案屬主為hc的檔案
    • 2. 在/etc目錄下查詢檔案屬主為hc的檔案:
    • 3. 為了查詢屬主帳戶已經被刪除的檔案,可以使用-nouser選項。在/home目錄下查詢所有的這類檔案
  • 五.使用group和nogroup選項:
  • 六.按照更改時間或訪問時間等查詢檔案:
  • 七.查詢比某個檔案新或舊的檔案:
    • 1.查詢更改時間比檔案log1新但比檔案log3舊的檔案
    • 2.查詢當前目錄下更改時間在比log2檔案新的檔案
  • 八.使用type選項:
    • 1:在/etc目錄下查詢所有的目錄
    • 2:在當前目錄下查詢除目錄以外的所有型別的檔案
    • 3:在/etc目錄下查詢所有的符號連結檔案
  • 九.使用size選項:
    • 1:在當前目錄下查詢檔案長度大於1 M位元組的檔案
    • 2:在/home/apache目錄下查詢檔案長度恰好為100位元組的檔案:
    • 3:在當前目錄下查詢長度超過10塊的檔案(一塊等於512位元組)
  • 十.使用depth選項:
    • 1:find命令從檔案系統的根目錄開始,查詢一個名為CON.FILE的檔案。
  • 十一.使用mount選項:
    • 1:從當前目錄開始查詢位於本檔案系統中檔名以XC結尾的檔案

 

 

一. name選項

檔名選項是find命令最常用的選項,要麼單獨使用該選項,要麼和其他選項一起使用。 可以使用某種檔名模式來匹配檔案,記住要用引號將檔名模式引起來。

不管當前路徑是什麼,如果想要在自己的根目錄$HOME中查詢檔名符合*.log的檔案,使用~作為 'pathname'引數,波浪號~代表了你的$HOME目錄。

find ~ -name "*.log" 

 

想要在當前目錄及子目錄中查詢所有的‘ *.log‘檔案,可以用:

find . -name "*.log" 

 

想要的當前目錄及子目錄中查詢檔名以一個大寫字母開頭的檔案,可以用:

find . -name "[A-Z]*" 

 

想要在/etc目錄中查詢檔名以host開頭的檔案,可以用:

find /etc -name "host*" 

 

想要查詢$HOME目錄中的檔案,可以用:

find ~ -name "*" 

 

要想讓系統高負荷執行,就從根目錄開始查詢所有的檔案。

find / -name "*" 

 

如果想在當前目錄查詢檔名以一個個小寫字母開頭,最後是4到9加上.log結束的檔案:

命令:

find . -name "[a-z]*[4-9].log" -print

 

 

二. perm選項

按照檔案許可權模式用-perm選項,按檔案許可權模式來查詢檔案的話。最好使用十進位制的許可權表示法。
如在當前目錄下查詢檔案許可權位為755的檔案,即檔案屬主可以讀、寫、執行,其他使用者可以讀、執行的檔案,可以用:

 find . -perm 755 

find -perm,根據檔案的許可權來查詢檔案,有三種形式:
find -perm mode
find -perm -mode
find -perm +mode

那麼這三者之間有什麼區別呢?解釋之前首先得簡單說一下linux中檔案許可權位的概念。在linux中檔案或目錄有三者許可權r,w,x,代表的含義分別是讀、寫、可執行。而一個檔案或目錄的屬性中又包括所屬使用者u、所屬組g、其他o三個部分的屬性,分別表示所屬使用者、所屬組、其他使用者對這個檔案所擁有的許可權。看起來大概是這個樣子:
所屬使用者 所屬組 其他
rwx rwx rwx

使用者在其擁有許可權的位上設定1,沒有許可權的位設定0。如果將每個部分的這些許可權位看成二進位制數,每個部分可以用3位二進位制數表示,最大值為7(2^3-1),表示可讀、可寫、可執行。嚴格的來說,檔案許可權除了r、w、x以外還有setuid,setgid許可權,等下再解釋。
好了,有了許可權位的基礎,那麼再來看find -perm mode。mode是三個數字表示的,每個數字最大值是7(原因前面解釋過了)。
find -perm mode , 表示嚴格匹配,也就是你的檔案許可權位轉換成對應的十進位制數字與mode一模一樣,那麼匹配成功,需要注意的是如果mode給的數字不足3位,那麼前面自動添0(嚴格的說是不足4位,原因就是前面所說的setuid,setgid,稍後解釋)

find -perm -mode , 表示mode中轉換成二進位制的1在檔案許可權位裡面必須匹配,比如mode=644那麼轉換成二進位制為110 100 100,而被查詢的檔案的許可權位也可以被轉換成一個二進位制數,兩者在位上為1的部分必須完全匹配,而0則不管。例如被查詢的檔案的許可權為轉換成二進位制數是111 111 111那麼這個比如被匹配,而假如是100 100 100那麼則不會匹配。所以這個'-'的作用歸結起來就是匹配比mode許可權更充足的檔案(找不到什麼詞語來形容了)

find -perm +mode , 與 -mode的區別是+mode只需其中的任意一個1的部分被匹配,-mode是所有1的部分都必須被匹配,同樣+mode也不管0位。

現在來解釋setuid,setgid,setuid許可權是用來使其他使用者可以“越權”執行你的命令,而本質上的實現就是在許可權檢查的時候,在程序的的有效UID裡面儲存了這個其他使用者的UID,所以許可權得驗證通過,這些許可權用一個新的3位二進位制數表示,有4,2,1三種值,4表示有setuid許可權,2表示有setgid許可權,1表示有粘著位(t)許可權(粘著位許可權最典型的例子是/tmp,每個使用者可以在裡面建立、更新、刪除自己建立(檔案所屬使用者是自己)的檔案,而不能更改別人的檔案)。

$ ls -l 
total 0
-rwxrwxrwx 1   fai     root       0 Aug 28 15:15 a
-rwxr-xr-x    1   fai     root       0 Aug 28 15:15 b
----rw----     1   fai     root       0 Aug 28 15:15 c
-rw-rw-rw-  1   fai     root       0 Aug 28 15:15 d
-r-xr--r--      1   fai     root       0 Aug 28 15:15 e

對於許可權進行十進位制轉2進位制
a(777):111 111 111
b(755):111 101 101
c(060): 000 110 000
d(666):110 110 110
e(544):101 100 100

$ find . -perm +006
.
./b
./d
./a
./e

mode中的006轉為2進位制是:000 000110
根據部分匹配的原則,只要在第3組中的第一或者第二位出現1就可以了,所以看到e檔案101只是匹配了第一位的1,但是也列印了。

而a檔案111的情況更是符合這個說法了。注意:c檔案雖然出現了110,但是不是對應的組,這個匹配是在相應位的。

$ find . -perm -006
./d
./a

對於-perm -006,也同樣道理去判斷,只是這裡需要完全匹配,也就是mode的二進位制中出現1的地方,目標中也要出現才行
需要在最後一組中的第一和第二位同時出現1才能匹配。
a(777):111 111 111
d(666):110 110 110

三. prune選項(此處引用http://blog.sina.com.cn/s/blog_6ad648f30100tqwy.html)

查詢時忽略指定目錄,是要使用-prune選項,但實際上最重要的還是要和path配合。-prune的意義是,當路徑字串匹配了path中指定的目錄時 候,find命令不進入這個目錄查詢,所以這個選項使用的關鍵,還是在path選項上的使用,也就是path選項和其他選項的配合使用,才能最後確定最終 結果。而path,實際上是對路徑字串的一個字元匹配,但也並不僅僅只匹配於目錄,檔案同樣可以被匹配,譬如存在一個目錄結構。

./01.txt
./02.txt
./03.txt
./aaa
./aaa/04.txt
./aaa/05.txt

find . -path "./aaa" -print 匹配中使用萬用字元,則會輸出

./aaa
./aaa/04.txt
./aaa/05.txt

而如果是find . -path "./aaa" -print ,嚴格等於./aaa目錄,則只輸出

./aaa

而且*萬用字元會將路徑中的字元"/"也作為普通字元進行貪婪匹配,所以可以匹配到目錄以下的檔案,所以在使用這個選項時候不要誤以為這個只對目錄有效,實際上只是一種路徑字元匹配工具。

1.查詢檔案時,忽略某個目錄

如果加上-prune,則第一個命令效果是:

find . -path "./aaa*" -prune -print

./aaa

因為加入了-prune,在匹配這個目錄同時禁止進入到這個目錄下搜尋,於是也就是我們所需要的不進入某個目錄查詢。

但如何配合其他選項來使用-path 以及-prune呢?以-name為例,下面對於配合使用方法進行一下演示。

我們先來看看純粹的-name和-path配合使用是什麼效果:

find -name "*.txt" -path "./aaa" -print

這個命令也相當於

find -name "*.txt" -a -path "./aaa" -print

但一般的-a都被忽略不寫。這個命令對於上面的目錄結構這個命令執行為空結果。也就是,既要檔名稱匹配".txt",同時又要其路徑字 串匹配"./aaa",而檔名匹配".txt"的結果有:

./01.txt
./02.txt
./03.txt
./aaa/04.txt
./aaa/05.txt

路徑字串匹配 "./aaa"的只有
./aaa
二者取and則為空結果,所以上面的命令輸出為空。

如果對-path選項加上-prune

find -name "*.txt" -path "./aaa" -prune -print

實際上與上面那條命令輸出並無區別,只是禁止進入./aaa下匹配而已,但最終的結果仍然是空。

再來看看很多人會誤用的結構:

find -name "*.txt" -path "./aaa" -prune -o -print

也就是比上一條語句在-print前增加一個-o。但實際上這條命令是將當前目錄以及包含./aaa子目錄下的所有檔案都打印出來。實際上
,這個語句先執行-o左側的語句,find -name "*.txt" -path "./aaa" -prune,因為匹配為空,則執行-o右側的語句-print,也就是把不匹配左側的檔名打印出來,既然左側沒有匹配為真的,所以也就是所有的檔案都被列印。

這裡要留意的是匹配模式項(比如-name "*.txt", -path ....),關係符( -a, -o, ","),與操作符(-print, -exec,- ok)之間的位置關係,特別是操作符在關係符的不同位置上,對於結果也具有決定的作用。

說明:

find [-path ..] [expression]

在路徑列表的後面的是表示式

-path "test" -prune -o -print 是 -path "test" -a -prune -o -print 的簡寫表示式按順序求值, -a 和 -o 都是短路求值,與 shell 的 && 和 || 類似如果

-path "test" 為真,則求值 -prune , -prune 返回真,與邏輯表示式為真;否則不求值 -prune,與邏輯表示式為假。如果 -path "test" -a -prune 為假,則求值 -print ,-print返回真,或邏輯表示式為真;否則不求值 -print,或邏輯表示式為真。

這個表示式組合特例可以用偽碼寫為:

if -path "test" then

-prune

else

-print

比如一個語句

find -name "*.txt" -print -o -path "./aaa" -prune -print             (1)

其實也可以略寫為

find -name "*.txt" -o -path "./aaa" -prune

注意第二個語句-o兩側都沒有-print,輸出結果為:

./01.txt
./02.txt
./03.txt
./aaa 

這是因為find開始執行,遇到第一個-print命令,則會考慮輸出,但是輸出的時候,則是將剩餘所有的匹配項一起進行匹配操作,也就是執行的是

find -name "*.txt" -print -o -path "./aaa" -prune  (注意-print命令的位置)

這個命令執行中相當於

find -path "./aaa" -prune -o -name "*.txt" -print

也 就是在匹配過程中,對於包含了-print部分的匹配項是最後匹配的,因此先匹配到了./aaa路徑,由於-prune的存在禁止進入這個路徑查詢,禁止 進入查詢,並不會因為-o選項而被逆轉,所以左側匹配了./aaa後,-o右側則是不匹配./aaa專案剩餘的檔案繼續去匹配-name模式,匹配的結果 最後被-print打印出來,這也就是我們所期待的忽略某個指定目錄進行搜尋的結果。

但是我們要分析的是命令(1)中的結果,命令(1)在遇到第一個-print命令後並執行了輸出,但是這個find命令中還存在第二個-print命令,所以在輸出

./01.txt
./02.txt
./03.txt

結果後,還是要繼續執行,要執行最後一個-print命令,下面的執行則相當於執行一個

find -name "*.txt" -o -path "./aaa" -prune -print

-o左側匹配-name "*.txt",-o到右側後則是對不能匹配到-name模式的結果,進行-path匹配,輸出結果為
./aaa
所以(1)命令最終的輸出結果就是

./01.txt
./02.txt
./03.txt
./aaa 。

 

2. 忽略多個資料夾

四. user和nouser 選項

1. 在$HOME目錄中查詢檔案屬主為hc的檔案

2. 在/etc目錄下查詢檔案屬主為hc的檔案:

3. 為了查詢屬主帳戶已經被刪除的檔案,可以使用-nouser選項。在/home目錄下查詢所有的這類檔案

五.使用group和nogroup選項:

六.按照更改時間或訪問時間等查詢檔案:

七.查詢比某個檔案新或舊的檔案:

1.查詢更改時間比檔案log1新但比檔案log3舊的檔案

2.查詢當前目錄下更改時間在比log2檔案新的檔案

八.使用type選項:

1:在/etc目錄下查詢所有的目錄

2:在當前目錄下查詢除目錄以外的所有型別的檔案

3:在/etc目錄下查詢所有的符號連結檔案

九.使用size選項:

1:在當前目錄下查詢檔案長度大於1 M位元組的檔案

2:在/home/apache目錄下查詢檔案長度恰好為100位元組的檔案:

3:在當前目錄下查詢長度超過10塊的檔案(一塊等於512位元組)

十.使用depth選項:

1:find命令從檔案系統的根目錄開始,查詢一個名為CON.FILE的檔案。

十一.使用mount選項:

1:從當前目錄開始查詢位於本檔案系統中檔名以XC結尾的檔案