鍍金池/ 教程/ Linux/ 查找文件
網(wǎng)絡(luò)系統(tǒng)
打印
重定向
使用命令
位置參數(shù)
權(quán)限
文本處理
疑難排解
layout: book-zh title: 自定制 shell 提示符
查找文件
layout: book-zh title: vi 簡介
shell 環(huán)境
什么是 shell
編譯程序
鍵盤高級操作技巧
流程控制:case 分支
流程控制:if 分支結(jié)構(gòu)
layout: book-zh title: 軟件包管理
進程
存儲媒介
格式化輸出
編寫第一個 Shell 腳本
啟動一個項目
流程控制:while/until 循環(huán)
文件系統(tǒng)中跳轉(zhuǎn)
字符串和數(shù)字
讀取鍵盤輸入
歸檔和備份
探究操作系統(tǒng)
流程控制:for 循環(huán)
自頂向下設(shè)計
數(shù)組
操作文件和目錄
奇珍異寶
從 shell 眼中看世界
正則表達式

查找文件

因為我們已經(jīng)瀏覽了 Linux 系統(tǒng),所以一件事已經(jīng)變得非常清楚:一個典型的 Linux 系統(tǒng)包含很多文件! 這就引發(fā)了一個問題,“我們怎樣查找東西?”。雖然我們已經(jīng)知道 Linux 文件系統(tǒng)良好的組織結(jié)構(gòu),是源自 類 Unix 的操作系統(tǒng)代代傳承的習(xí)俗。但是僅文件數(shù)量就會引起可怕的問題。在這一章中,我們將察看 兩個用來在系統(tǒng)中查找文件的工具。這些工具是:

  • locate – 通過名字來查找文件

  • find – 在目錄層次結(jié)構(gòu)中搜索文件

我們也將看一個經(jīng)常與文件搜索命令一起使用的命令,它用來處理搜索到的文件列表:

  • xargs – 從標(biāo)準(zhǔn)輸入生成和執(zhí)行命令行

另外,我們將介紹兩個命令來協(xié)助我們探索:

  • touch – 更改文件時間

  • stat – 顯示文件或文件系統(tǒng)狀態(tài)

locate - 查找文件的簡單方法

這個 locate 程序快速搜索路徑名數(shù)據(jù)庫,并且輸出每個與給定字符串相匹配的文件名。比如說, 例如,我們想要找到所有名字以“zip”開頭的程序。因為我們正在查找程序,可以假定包含 匹配程序的目錄以"bin/"結(jié)尾。因此,我們試著以這種方式使用 locate 命令,來找到我們的文件:

[me@linuxbox ~]$ locate bin/zip

locate 命令將會搜索它的路徑名數(shù)據(jù)庫,輸出任一個包含字符串“bin/zip”的路徑名:

/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit

如果搜索要求沒有這么簡單,locate 可以結(jié)合其它工具,比如說 grep 命令,來設(shè)計更加 有趣的搜索:

[me@linuxbox ~]$ locate zip | grep bin
/bin/bunzip2
/bin/bzip2
/bin/bzip2recover
/bin/gunzip
/bin/gzip
/usr/bin/funzip
/usr/bin/gpg-zip
/usr/bin/preunzip
/usr/bin/prezip
/usr/bin/prezip-bin
/usr/bin/unzip
/usr/bin/unzipsfx
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit

這個 locate 程序已經(jīng)存在了很多年了,它有幾個不同的變體被普遍使用著。在現(xiàn)在 Linux 發(fā)行版中發(fā)現(xiàn)的兩個最常見的變體是 slocate 和 mlocate,但是通常它們被名為 locate 的 符號鏈接訪問。不同版本的 locate 命令擁有重復(fù)的選項集合。一些版本包括正則表達式 匹配(我們會在下一章中討論)和通配符支持。查看 locate 命令的手冊,從而確定安裝了 哪個版本的 locate 程序。

locate 數(shù)據(jù)庫來自何方?

你可能注意到了,在一些發(fā)行版中,僅僅在系統(tǒng)安裝之后,locate 不能工作, 但是如果你第二天再試一下,它就工作正常了。怎么回事呢?locate 數(shù)據(jù)庫由另一個叫做 updatedb 的程序創(chuàng)建。通常,這個程序作為一個 cron 工作例程周期性運轉(zhuǎn);也就是說,一個任務(wù) 在特定的時間間隔內(nèi)被 cron 守護進程執(zhí)行。大多數(shù)裝有 locate 的系統(tǒng)會每隔一天運行一回 updatedb 程序。因為數(shù)據(jù)庫不能被持續(xù)地更新,所以當(dāng)使用 locate 時,你會發(fā)現(xiàn) 目前最新的文件不會出現(xiàn)。為了克服這個問題,可以手動運行 updatedb 程序, 更改為超級用戶身份,在提示符下運行 updatedb 命令。

find - 查找文件的復(fù)雜方式

locate 程序只能依據(jù)文件名來查找文件,而 find 程序能基于各種各樣的屬性, 搜索一個給定目錄(以及它的子目錄),來查找文件。我們將要花費大量的時間學(xué)習(xí) find 命令,因為 它有許多有趣的特性,當(dāng)我們開始在隨后的章節(jié)里面討論編程概念的時候,我們將會重復(fù)看到這些特性。

find 命令的最簡單使用是,搜索一個或多個目錄。例如,輸出我們的家目錄列表。

[me@linuxbox ~]$ find ~

對于最活躍的用戶帳號,這將產(chǎn)生一張很大的列表。因為這張列表被發(fā)送到標(biāo)準(zhǔn)輸出, 我們可以把這個列表管道到其它的程序中。讓我們使用 wc 程序來計算出文件的數(shù)量:

[me@linuxbox ~]$ find ~ | wc -l
47068

哇,我們一直很忙!find 命令的美麗所在就是它能夠被用來識別符合特定標(biāo)準(zhǔn)的文件。它通過 (有點奇怪)應(yīng)用選項,測試條件,和操作來完成搜索。我們先看一下測試條件。

Tests

比如說我們想要目錄列表。我們可以添加以下測試條件:

[me@linuxbox ~]$ find ~ -type d | wc -l
1695

添加測試條件-type d 限制了只搜索目錄。相反地,我們使用這個測試條件來限定搜索普通文件:

[me@linuxbox ~]$ find ~ -type f | wc -l
38737

這里是 find 命令支持的普通文件類型測試條件:

表18-1: find 文件類型
文件類型 描述
b 塊設(shè)備文件
c 字符設(shè)備文件
d 目錄
f 普通文件
l 符號鏈接

我們也可以通過加入一些額外的測試條件,根據(jù)文件大小和文件名來搜索:讓我們查找所有文件名匹配 通配符模式“*.JPG”和文件大小大于1M 的文件:

[me@linuxbox ~]$ find ~ -type f -name "\*.JPG" -size +1M | wc -l
840

在這個例子里面,我們加入了 -name 測試條件,后面跟通配符模式。注意,我們把它用雙引號引起來, 從而阻止 shell 展開路徑名。緊接著,我們加入 -size 測試條件,后跟字符串“+1M”。開頭的加號表明 我們正在尋找文件大小大于指定數(shù)的文件。若字符串以減號開頭,則意味著查找小于指定數(shù)的文件。 若沒有符號意味著“精確匹配這個數(shù)”。結(jié)尾字母“M”表明測量單位是兆字節(jié)。下面的字符可以 被用來指定測量單位:

表18-2: find 大小單位
字符 單位
b 512 個字節(jié)塊。如果沒有指定單位,則這是默認值。
c 字節(jié)
w 兩個字節(jié)的字
k 千字節(jié)(1024個字節(jié)單位)
M 兆字節(jié)(1048576個字節(jié)單位)
G 千兆字節(jié)(1073741824個字節(jié)單位)

find 命令支持大量不同的測試條件。下表是列出了一些常見的測試條件。請注意,在需要數(shù)值參數(shù)的 情況下,可以應(yīng)用以上討論的“+”和"-"符號表示法:

表18-3: find 測試條件
測試條件 描述
-cmin n 匹配的文件和目錄的內(nèi)容或?qū)傩宰詈笮薷臅r間正好在 n 分鐘之前。 指定少于 n 分鐘之前,使用 -n,指定多于 n 分鐘之前,使用 +n。
-cnewer file 匹配的文件和目錄的內(nèi)容或?qū)傩宰詈笮薷臅r間早于那些文件。
-ctime n 匹配的文件和目錄的內(nèi)容和屬性最后修改時間在 n\*24小時之前。
-empty 匹配空文件和目錄。
-group name 匹配的文件和目錄屬于一個組。組可以用組名或組 ID 來表示。
-iname pattern 就像-name 測試條件,但是不區(qū)分大小寫。
-inum n 匹配的文件的 inode 號是 n。這對于找到某個特殊 inode 的所有硬鏈接很有幫助。
-mmin n 匹配的文件或目錄的內(nèi)容被修改于 n 分鐘之前。
-mtime n 匹配的文件或目錄的內(nèi)容被修改于 n\*24小時之前。
-name pattern 用指定的通配符模式匹配的文件和目錄。
-newer file 匹配的文件和目錄的內(nèi)容早于指定的文件。當(dāng)編寫 shell 腳本,做文件備份時,非常有幫助。 每次你制作一個備份,更新文件(比如說日志),然后使用 find 命令來決定自從上次更新,哪一個文件已經(jīng)更改了。
-nouser 匹配的文件和目錄不屬于一個有效用戶。這可以用來查找 屬于刪除帳戶的文件或監(jiān)測攻擊行為。
-nogroup 匹配的文件和目錄不屬于一個有效的組。
-perm mode 匹配的文件和目錄的權(quán)限已經(jīng)設(shè)置為指定的 mode。mode 可以用 八進制或符號表示法。
-samefile name 相似于-inum 測試條件。匹配和文件 name 享有同樣 inode 號的文件。
-size n 匹配的文件大小為 n。
-type c 匹配的文件類型是 c。
-user name 匹配的文件或目錄屬于某個用戶。這個用戶可以通過用戶名或用戶 ID 來表示。

這不是一個完整的列表。find 命令手冊有更詳細的說明。

操作符

即使擁有了 find 命令提供的所有測試條件,我們還需要一個更好的方式來描述測試條件之間的邏輯關(guān)系。例如, 如果我們需要確定是否一個目錄中的所有的文件和子目錄擁有安全權(quán)限,怎么辦呢? 我們可以查找權(quán)限不是0600的文件和權(quán)限不是0700的目錄。幸運地是,find 命令提供了 一種方法來結(jié)合測試條件,通過使用邏輯操作符來創(chuàng)建更復(fù)雜的邏輯關(guān)系。 為了表達上述的測試條件,我們可以這樣做:

[me@linuxbox ~]$ find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)

呀!這的確看起來很奇怪。這些是什么東西?實際上,這些操作符沒有那么復(fù)雜,一旦你知道了它們的原理。 這里是操作符列表:

表18-4: find 命令的邏輯操作符
操作符 描述
-and 如果操作符兩邊的測試條件都是真,則匹配。可以簡寫為 -a。 注意若沒有使用操作符,則默認使用 -and。
-or 若操作符兩邊的任一個測試條件為真,則匹配。可以簡寫為 -o。
-not 若操作符后面的測試條件是真,則匹配??梢院唽憺橐粋€感嘆號(!)。
() 把測試條件和操作符組合起來形成更大的表達式。這用來控制邏輯計算的優(yōu)先級。 默認情況下,find 命令按照從左到右的順序計算。經(jīng)常有必要重寫默認的求值順序,以得到期望的結(jié)果。 即使沒有必要,有時候包括組合起來的字符,對提高命令的可讀性是很有幫助的。注意 因為圓括號字符對于 shell 來說有特殊含義,所以在命令行中使用它們的時候,它們必須 用引號引起來,才能作為實參傳遞給 find 命令。通常反斜杠字符被用來轉(zhuǎn)義圓括號字符。

通過這張操作符列表,我們重建 find 命令。從最外層看,我們看到測試條件被分為兩組,由一個 -or 操作符分開:

( expression 1 ) -or ( expression 2 )

這很有意義,因為我們正在搜索具有不同權(quán)限集合的文件和目錄。如果我們文件和目錄兩者都查找, 那為什么要用 -or 來代替 -and 呢?因為 find 命令掃描文件和目錄時,會計算每一個對象,看看它是否 匹配指定的測試條件。我們想要知道它是具有錯誤權(quán)限的文件還是有錯誤權(quán)限的目錄。它不可能同時符合這 兩個條件。所以如果展開組合起來的表達式,我們能這樣解釋它:

( file with bad perms ) -or ( directory with bad perms )

下一個挑戰(zhàn)是怎樣來檢查“錯誤權(quán)限”,這個怎樣做呢?我們不從這個角度做。我們將測試 “不是正確權(quán)限”,因為我們知道什么是“正確權(quán)限”。對于文件,我們定義正確權(quán)限為0600, 目錄則為0711。測試具有“不正確”權(quán)限的文件表達式為:

-type f -and -not -perms 0600

對于目錄,表達式為:

-type d -and -not -perms 0700

正如上述操作符列表中提到的,這個-and 操作符能夠被安全地刪除,因為它是默認使用的操作符。 所以如果我們把這兩個表達式連起來,就得到最終的命令:

find ~ ( -type f -not -perms 0600 ) -or ( -type d -not -perms 0700 )

然而,因為圓括號對于 shell 有特殊含義,我們必須轉(zhuǎn)義它們,來阻止 shell 解釋它們。在圓括號字符 之前加上一個反斜杠字符來轉(zhuǎn)義它們。

邏輯操作符的另一個特性要重點理解。比方說我們有兩個由邏輯操作符分開的表達式:

expr1 -operator expr2

在所有情況下,總會執(zhí)行表達式 expr1;然而由操作符來決定是否執(zhí)行表達式 expr2。這里 列出了它是怎樣工作的:

表18-5: find AND/OR 邏輯
expr1 的結(jié)果 操作符 expr2 is...
-and 總要執(zhí)行
-and 從不執(zhí)行
-or 從不執(zhí)行
-or 總要執(zhí)行

為什么這會發(fā)生呢?這樣做是為了提高性能。以 -and 為例,我們知道表達式 expr1 -and expr2 不能為真,如果表達式 expr1的結(jié)果為假,所以沒有必要執(zhí)行 expr2。同樣地,如果我們有表達式 expr1 -or expr2,并且表達式 expr1的結(jié)果為真,那么就沒有必要執(zhí)行 expr2,因為我們已經(jīng)知道 表達式 expr1 -or expr2 為真。好,這樣會執(zhí)行快一些。為什么這個很重要? 它很重要是因為我們能依靠這種行為來控制怎樣來執(zhí)行操作。我們會很快看到...

預(yù)定義的操作

讓我們做一些工作吧!從 find 命令得到的結(jié)果列表很有用處,但是我們真正想要做的事情是操作列表 中的某些條目。幸運地是,find 命令允許基于搜索結(jié)果來執(zhí)行操作。有許多預(yù)定義的操作和幾種方式來 應(yīng)用用戶定義的操作。首先,讓我們看一下幾個預(yù)定義的操作:

表18-6: 幾個預(yù)定義的 find 命令操作
操作 描述
-delete 刪除當(dāng)前匹配的文件。
-ls 對匹配的文件執(zhí)行等同的 ls -dils 命令。并將結(jié)果發(fā)送到標(biāo)準(zhǔn)輸出。
-print 把匹配文件的全路徑名輸送到標(biāo)準(zhǔn)輸出。如果沒有指定其它操作,這是 默認操作。
-quit 一旦找到一個匹配,退出。

和測試條件一樣,還有更多的操作。查看 find 命令手冊得到更多細節(jié)。在第一個例子里, 我們這樣做:

find ~

這個命令輸出了我們家目錄中包含的每個文件和子目錄。它會輸出一個列表,因為會默認使用-print 操作 ,如果沒有指定其它操作的話。因此我們的命令也可以這樣表述:

find ~ -print

我們可以使用 find 命令來刪除符合一定條件的文件。例如,來刪除擴展名為“.BAK”(這通常用來指定備份文件) 的文件,我們可以使用這個命令:

find ~ -type f -name '*.BAK' -delete

在這個例子里面,用戶家目錄(和它的子目錄)下搜索每個以.BAK 結(jié)尾的文件名。當(dāng)找到后,就刪除它們。


警告:當(dāng)使用 -delete 操作時,不用說,你應(yīng)該格外小心。首先測試一下命令, 用 -print 操作代替 -delete,來確認搜索結(jié)果。


在我們繼續(xù)之前,讓我們看一下邏輯運算符是怎樣影響操作的??紤]以下命令:

find ~ -type f -name '*.BAK' -print

正如我們所見到的,這個命令會查找每個文件名以.BAK (-name '*.BAK') 結(jié)尾的普通文件 (-type f), 并把每個匹配文件的相對路徑名輸出到標(biāo)準(zhǔn)輸出 (-print)。然而,此命令按這個方式執(zhí)行的原因,是 由每個測試和操作之間的邏輯關(guān)系決定的。記住,在每個測試和操作之間會默認應(yīng)用 -and 邏輯運算符。 我們也可以這樣表達這個命令,使邏輯關(guān)系更容易看出:

find ~ -type f -and -name '*.BAK' -and -print

當(dāng)命令被充分表達之后,讓我們看看邏輯運算符是如何影響其執(zhí)行的:

測試/行為 只有...的時候,才被執(zhí)行
-print 只有 -type f and -name '*.BAK'為真的時候
-name ‘*.BAK’ 只有 -type f 為真的時候
-type f 總是被執(zhí)行,因為它是與 -and 關(guān)系中的第一個測試/行為。

因為測試和行為之間的邏輯關(guān)系決定了哪一個會被執(zhí)行,我們知道測試和行為的順序很重要。例如, 如果我們重新安排測試和行為之間的順序,讓 -print 行為是第一個,那么這個命令執(zhí)行起來會截然不同:

find ~ -print -and -type f -and -name '*.BAK'

這個版本的命令會打印出每個文件(-print 行為總是為真),然后測試文件類型和指定的文件擴展名。

用戶定義的行為

除了預(yù)定義的行為之外,我們也可以喚醒隨意的命令。傳統(tǒng)方式是通過 -exec 行為。這個 行為像這樣工作:

-exec command {} ;

這里的 command 就是指一個命令的名字,{}是當(dāng)前路徑名的符號表示,分號是要求的界定符 表明命令結(jié)束。這里是一個使用 -exec 行為的例子,其作用如之前討論的 -delete 行為:

-exec rm '{}' ';'

重述一遍,因為花括號和分號對于 shell 有特殊含義,所以它們必須被引起來或被轉(zhuǎn)義。

也有可能交互式地執(zhí)行一個用戶定義的行為。通過使用 -ok 行為來代替 -exec,在執(zhí)行每個指定的命令之前, 會提示用戶:

find ~ -type f -name 'foo*' -ok ls -l '{}' ';'
< ls ... /home/me/bin/foo > ? y
-rwxr-xr-x 1 me    me 224 2007-10-29 18:44 /home/me/bin/foo
< ls ... /home/me/foo.txt > ? y
-rw-r--r-- 1 me    me 0 2008-09-19 12:53 /home/me/foo.txt

在這個例子里面,我們搜索以字符串“foo”開頭的文件名,并且對每個匹配的文件執(zhí)行 ls -l 命令。 使用 -ok 行為,會在 ls 命令執(zhí)行之前提示用戶。

提高效率

當(dāng) -exec 行為被使用的時候,若每次找到一個匹配的文件,它會啟動一個新的指定命令的實例。 我們可能更愿意把所有的搜索結(jié)果結(jié)合起來,再運行一個命令的實例。例如,而不是像這樣執(zhí)行命令:

ls -l file1
ls -l file2

我們更喜歡這樣執(zhí)行命令:

ls -l file1 file2

這樣就導(dǎo)致命令只被執(zhí)行一次而不是多次。有兩種方法可以這樣做。傳統(tǒng)方式是使用外部命令 xargs,另一種方法是,使用 find 命令自己的一個新功能。我們先討論第二種方法。

通過把末尾的分號改為加號,就激活了 find 命令的一個功能,把搜索結(jié)果結(jié)合為一個參數(shù)列表, 然后執(zhí)行一次所期望的命令。再看一下之前的例子,這個:

find ~ -type f -name 'foo*' -exec ls -l '{}' ';'
-rwxr-xr-x 1 me     me 224 2007-10-29 18:44 /home/me/bin/foo
-rw-r--r-- 1 me     me 0 2008-09-19 12:53 /home/me/foo.txt

會執(zhí)行 ls 命令,每次找到一個匹配的文件。把命令改為:

find ~ -type f -name 'foo*' -exec ls -l '{}' +
-rwxr-xr-x 1 me     me 224 2007-10-29 18:44 /home/me/bin/foo
-rw-r--r-- 1 me     me 0 2008-09-19 12:53 /home/me/foo.txt

雖然我們得到一樣的結(jié)果,但是系統(tǒng)只需要執(zhí)行一次 ls 命令。

xargs

這個 xargs 命令會執(zhí)行一個有趣的函數(shù)。它從標(biāo)準(zhǔn)輸入接受輸入,并把輸入轉(zhuǎn)換為一個特定命令的 參數(shù)列表。對于我們的例子,我們可以這樣使用它:

find ~ -type f -name 'foo\*' -print | xargs ls -l
-rwxr-xr-x 1 me     me 224 2007-10-29 18:44 /home/me/bin/foo
-rw-r--r-- 1 me     me 0 2008-09-19 12:53 /home/me/foo.txt

這里我們看到 find 命令的輸出被管道到 xargs 命令,反過來,xargs 會為 ls 命令構(gòu)建 參數(shù)列表,然后執(zhí)行 ls 命令。


注意:當(dāng)被放置到命令行中的參數(shù)個數(shù)相當(dāng)大時,參數(shù)個數(shù)是有限制的。有可能創(chuàng)建的命令 太長以至于 shell 不能接受。當(dāng)命令行超過系統(tǒng)支持的最大長度時,xargs 會執(zhí)行帶有最大 參數(shù)個數(shù)的指定命令,然后重復(fù)這個過程直到耗盡標(biāo)準(zhǔn)輸入。執(zhí)行帶有 --show--limits 選項 的 xargs 命令,來查看命令行的最大值。


處理古怪的文件名

類 Unix 的系統(tǒng)允許在文件名中嵌入空格(甚至換行符)。這就給一些程序,如為其它 程序構(gòu)建參數(shù)列表的 xargs 程序,造成了問題。一個嵌入的空格會被看作是一個界定符,生成的 命令會把每個空格分離的單詞解釋為單獨的參數(shù)。為了解決這個問題,find 命令和 xarg 程序 允許可選擇的使用一個 null 字符作為參數(shù)分隔符。一個 null 字符被定義在 ASCII 碼中,由數(shù)字 零來表示(相反的,例如,空格字符在 ASCII 碼中由數(shù)字32表示)。find 命令提供的 -print0 行為, 則會產(chǎn)生由 null 字符分離的輸出,并且 xargs 命令有一個 --null 選項,這個選項會接受由 null 字符 分離的輸入。這里有一個例子:

find ~ -iname '*.jpg' -print0 | xargs --null ls -l

使用這項技術(shù),我們可以保證所有文件,甚至那些文件名中包含空格的文件,都能被正確地處理。

返回操練場

到實際使用 find 命令的時候了。我們將會創(chuàng)建一個操練場,來實踐一些我們所學(xué)到的知識。

首先,讓我們創(chuàng)建一個包含許多子目錄和文件的操練場:

[me@linuxbox ~]$ mkdir -p playground/dir-{00{1..9},0{10..99},100}
[me@linuxbox ~]$ touch playground/dir-{00{1..9},0{10..99},100}/file-{A..Z}

驚嘆于命令行的強大功能!只用這兩行,我們就創(chuàng)建了一個包含一百個子目錄,每個子目錄中 包含了26個空文件的操練場。試試用 GUI 來創(chuàng)建它!

我們用來創(chuàng)造這個奇跡的方法中包含一個熟悉的命令(mkdir),一個奇異的 shell 擴展(大括號) 和一個新命令,touch。通過結(jié)合 mkdir 命令和-p 選項(導(dǎo)致 mkdir 命令創(chuàng)建指定路徑的父目錄),以及 大括號展開,我們能夠創(chuàng)建一百個目錄。

這個 touch 命令通常被用來設(shè)置或更新文件的訪問,更改,和修改時間。然而,如果一個文件名參數(shù)是一個 不存在的文件,則會創(chuàng)建一個空文件。

在我們的操練場中,我們創(chuàng)建了一百個名為 file-A 的文件實例。讓我們找到它們:

[me@linuxbox ~]$ find playground -type f -name 'file-A'

注意不同于 ls 命令,find 命令的輸出結(jié)果是無序的。其順序由存儲設(shè)備的布局決定。為了確定實際上 我們擁有一百個此文件的實例,我們可以用這種方式來確認:

[me@linuxbox ~]$ find playground -type f -name 'file-A' | wc -l

下一步,讓我們看一下基于文件的修改時間來查找文件。當(dāng)創(chuàng)建備份文件或者以年代順序來 組織文件的時候,這會很有幫助。為此,首先我們將創(chuàng)建一個參考文件,我們將與其比較修改時間:

[me@linuxbox ~]$ touch playground/timestamp

這個創(chuàng)建了一個空文件,名為 timestamp,并且把它的修改時間設(shè)置為當(dāng)前時間。我們能夠驗證 它通過使用另一個方便的命令,stat,是一款加大馬力的 ls 命令版本。這個 stat 命令會展示系統(tǒng)對 某個文件及其屬性所知道的所有信息:

[me@linuxbox ~]$ stat playground/timestamp
File: 'playground/timestamp'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 803h/2051d Inode: 14265061 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/ me) Gid: ( 1001/ me)
Access: 2008-10-08 15:15:39.000000000 -0400
Modify: 2008-10-08 15:15:39.000000000 -0400
Change: 2008-10-08 15:15:39.000000000 -0400

如果我們再次 touch 這個文件,然后用 stat 命令檢測它,我們會發(fā)現(xiàn)所有文件的時間已經(jīng)更新了。

[me@linuxbox ~]$ touch playground/timestamp
[me@linuxbox ~]$ stat playground/timestamp
File: 'playground/timestamp'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 803h/2051d Inode: 14265061 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/ me) Gid: ( 1001/ me)
Access: 2008-10-08 15:23:33.000000000 -0400
Modify: 2008-10-08 15:23:33.000000000 -0400
Change: 2008-10-08 15:23:33.000000000 -0400

下一步,讓我們使用 find 命令來更新一些操練場中的文件:

[me@linuxbox ~]$ find playground -type f -name 'file-B' -exec touch '{}' ';'

這會更新操練場中所有名為 file-B 的文件。接下來我們會使用 find 命令來識別已更新的文件, 通過把所有文件與參考文件 timestamp 做比較:

[me@linuxbox ~]$ find playground -type f -newer playground/timestamp

搜索結(jié)果包含所有一百個文件 file-B 的實例。因為我們在更新了文件 timestamp 之后, touch 了操練場中名為 file-B 的所有文件,所以現(xiàn)在它們“新于”timestamp 文件,因此能被用 -newer 測試條件識別出來。

最后,讓我們回到之前那個錯誤權(quán)限的例子中,把它應(yīng)用于操練場里:

[me@linuxbox ~]$ find playground \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)

這個命令列出了操練場中所有一百個目錄和二百六十個文件(還有 timestamp 和操練場本身,共 2702 個) ,因為沒有一個符合我們“正確權(quán)限”的定義。通過對運算符和行為知識的了解,我們可以給這個命令 添加行為,對實戰(zhàn)場中的文件和目錄應(yīng)用新的權(quán)限。

[me@linuxbox ~]$ find playground \( -type f -not -perm 0600 -exec chmod 0600 '{}' ';' \)
   -or \( -type d -not -perm 0711 -exec chmod 0700 '{}' ';' \)

在日常的基礎(chǔ)上,我們可能發(fā)現(xiàn)運行兩個命令會比較容易一些,一個操作目錄,另一個操作文件, 而不是這一個長長的復(fù)合命令,但是很高興知道,我們能這樣執(zhí)行命令。這里最重要的一點是要 理解怎樣把操作符和行為結(jié)合起來使用,來執(zhí)行有用的任務(wù)。

選項

最后,我們有這些選項。這些選項被用來控制 find 命令的搜索范圍。當(dāng)構(gòu)建 find 表達式的時候, 它們可能被其它的測試條件和行為包含:

表 18-7: find 命令選項
選項 描述
-depth 指導(dǎo) find 程序先處理目錄中的文件,再處理目錄自身。當(dāng)指定-delete 行為時,會自動 應(yīng)用這個選項。
-maxdepth levels 當(dāng)執(zhí)行測試條件和行為的時候,設(shè)置 find 程序陷入目錄樹的最大級別數(shù)
-mindepth levels 在應(yīng)用測試條件和行為之前,設(shè)置 find 程序陷入目錄數(shù)的最小級別數(shù)。
-mount 指導(dǎo) find 程序不要搜索掛載到其它文件系統(tǒng)上的目錄。
-noleaf 指導(dǎo) find 程序不要基于搜索類 Unix 的文件系統(tǒng)做出的假設(shè),來優(yōu)化它的搜索。

拓展閱讀

  • 程序 locate,updatedb,find 和 xargs 都是 GNU 項目 findutils 軟件包的一部分。 這個 GUN 項目提供了大量的在線文檔,這些文檔相當(dāng)出色,如果你在高安全性的 環(huán)境中使用這些程序,你應(yīng)該讀讀這些文檔。

    http://www.gnu.org/software/findutils/

上一篇:操作文件和目錄下一篇:歸檔和備份