Linux Find 命令精通指南

來源:互聯網
上載者:User

作者:Sheryl Calish
簡單介紹這一無處不在的命令的強大的方面以及混亂的方面。
2008 年 7 月發布
Linux find 命令是所有 Linux 命令中最有用的一個,同時也是最混亂的一個。它很難,因為它的文法與其他 Linux 命令的標準文法不同。但是,它很強大,因為它允許您按檔案名稱、檔案類型、使用者甚至是時間戳記尋找檔案。使用 find 命令,您不但可以找到具這些屬性任意組合的檔案,還可以對它找到的檔案執行操作。
本文的目的是,通過概述 find 命令的用途和潛能,簡化該命令的學習和使用。同時,它將針對 find 命令的某些最強大但最混亂的方面提供一個基本的指南和參考。
[注意:本文使用的 find 版本是 GNU 版本,因此,某些細節可能與其他版本的 find 有所不同。] 基本格式
開始之前,我們先來看一下 find 命令的基本結構:
find   start_directory  test  options   criteria_to_match action_to_perform_on_results                          
在以下命令中,find 將開始在目前的目錄(用“.”表示)中尋找任何副檔名為“java”的檔案:
find . -name  "*.java"  
下面是該命令所找到的命令的縮減清單:
find . -name  "*.java" ./REGEXPvalidate/src/oracle/otnsamples/plsql/ConnectionManager.java ./REGEXPvalidate/src/oracle/otnsamples/plsql/DBManager.java ..
[注意:如果您從本文剪下並粘貼來運行該 find 命令,您可能需要使用自己的鍵盤替換雙引號 (“”) 才能得出正確的結果。]
以下命令將執行相同的操作。在這兩種情況下,您都需要對萬用字元進行轉義以確保它傳遞到 find 命令並且不由 shell 解釋。因此,請將您的搜尋字串放到引號裡,或者在它前面加上反斜線:
find . -name  \*.java
儘管 find 的所有參數均為可選,但是如果您未指定從哪裡開始搜尋,搜尋預設將在目前的目錄中開始。如果您不指定要匹配的測試連接、選項或值,您的結果將不完整或者無區別。
運行以下三個 find 命令將得出同樣的結果 — 目前的目錄和所有子目錄中的所有檔案(包括隱藏檔案)的完整清單:
find find . find . -print
這類似於運行一個帶 -la 選項的 ls 命令。如果您希望上述命令的輸出包含完整的路徑名(或許是為了備份),您將需要指定起始目錄的完整路徑:
find /home/bluher -name \*.java /home/bluher/plsql/REGEXPvalidate/src/oracle/otnsamples/plsql/ConnectionManager.java /home/bluher/plsql/REGEXPvalidate/src/oracle/otnsamples/plsql/DBManager.java/ ...
您還可以在搜尋字串中指定多個起始目錄。如果以具有相應許可權的使用者身份運行,以下命令將下到 /usr、/home /tmp 目錄尋找所有 jar 檔案:
find /usr /home  /tmp -name "*.jar"
但是,如果您沒有相應的許可權,您在開始瀏覽許多系統目錄時將建置錯誤訊息。以下是一個樣本:
find:  /tmp/orbit-root: Permission denied
您可以通過附加您的搜尋字串來避免混亂的輸出,如下所示:
find /usr /home  /tmp -name "*.jar" 2>/dev/null
這會將所有錯誤訊息發送到空檔案,因此提供清除程式輸出。
預設情況下,find 是區分大小寫。對於不區分大小寫 find,將 -iname 測試替換為 -name 測試。
find downloads  -iname "*.gif" downloads/.xvpics/Calendar05_enlarged.gif downloads/lcmgcfexsmall.GIF
除檔案名稱外,您還可以按類型搜尋檔案。例如,您可以使用以下命令尋找一個目錄中的所有子目錄:
find . -type d         
您可以使用以下命令尋找您的/usr 目錄中的所有符號連結:
find /usr -type l
這可能會列出 3,000 多個連結。以下的任何一個命令使用根許可權運行都將列出 /usr 目錄中的連結以及它所指向的檔案:
# find /usr/bin  -type l  -name "z*" -exec ls  -l {} \; lrwxrwxrwx 1 root  root 8 Dec 12 23:17 /usr/bin/zsh -> /bin/zsh lrwxrwxrwx 1 root  root 5 Dec 12 23:17 /usr/bin/zless -> zmore lrwxrwxrwx 1 root  root 9 Dec 12 23:17 /usr/bin/zcat -> /bin/zcat
find /usr/bin -type  l  -name "z*" -ls
但是,第二個更短的命令將列出更多的檔案,以及目錄和 inode 資訊:在本文後面的部分中,我們將討論 -exec 和 -ls 操作的用法。
其他 find 可以找到的檔案類型包括:
• b — 塊(緩衝)特殊 • c — 字元(未緩衝)特殊 • p — 具名管道 (FIFO) • s — 通訊端
使用根作為 find 命令的起點會極大地降低系統的速度。如果您必須運行這樣一個命令,您可以在非高峰時段或晚上運行它。您可以使用以下文法將輸出重新導向到一個檔案:
find  /   -print > masterfilelist.out
如果您錯誤地輸入一個 find 命令,產生大量不必要的輸出,只需按 CTRL-C 中斷該命令,這將停止最近執行的命令。
在具多個檔案系統的商業網路上,限制 find 尋找的檔案也是一個特別好用的方法。儘可能多地使用選項和測試以減少系統上的負載。用於此目的的兩個最有用的選項是 -xdev 和 -mount。它們通過阻止 find 下到其他檔案系統(如 MS-DOS、CD-ROM 或 AFS)上的目錄中縮短了搜尋範圍。這將搜尋限制為同一類型的檔案系統作為起始目錄。
如果運行 mount 命令,雙引導系統上的使用者可以使用這些選項。假設涉及 Windows 分區,您可以使用類似以下的命令安裝它:
mount -t vfat  /dev/sda1 /mnt/msdos
您使用的實際命令取決於您的系統設定。您可以通過運行 df 或執行以下命令驗證該分區已安裝:
find /mnt/msdos  -name "*.txt" 2> /dev/null
您應該看到 MS Windows 分區上列出了很多的檔案。現在,運行以下帶 -mount 或 -xdev 選項的命令:
find / -name  "*.txt" -mount 2> /dev/null
或者
find / -name  "*.txt" -xdev 2> /dev/null
還可以使用 -fstype 測試明確告知 find 在哪個檔案系統中尋找,如以下樣本中所示:
find / -name  "*.txt" -fstype vfat 2> /dev/null
尋找時間
find 命令有幾個用於根據您系統的時間戳記搜尋檔案的選項。這些時間戳記包括
• mtime — 檔案內容上次修改時間 • atime — 檔案被讀取或訪問的時間 • ctime — 檔案狀態變化時間
mtime 和 atime 的含義都是很容易理解的,而 ctime 則需要更多的解釋。由於 inode 維護著每個檔案上的中繼資料,因此,如果與檔案有關的中繼資料發生變化,則 inode 資料也將變化。這可能是由一系列操作引起的,包括建立到檔案的符號連結、變更檔許可權或移動了檔案等。由於在這些情況下,檔案內容不會被讀取或修改,因此 mtime 和 atime 不會改變,但 ctime 將發生變化。
這些時間選項都需要與一個值 n 結合使用,指定為 -n、n 或 +n。
• -n 返回項小於 n • +n 返回項大於 n • n 返回項正好與 n 相等
下面,我們來看幾個例子,以便於理解。以下命令將尋找在最近 1 小時內修改的所有檔案:
find . -mtime -1 ./plsql/FORALLSample ./plsql/RegExpDNASample /plsql/RegExpSample
用 1 取代 -1 運行同一命令將尋找恰好在 1 小時以前修改的所有檔案:
find . -mtime 1
上述命令不會產生任何結果,因為它要求完全吻合。以下命令尋找 1 個多小時以前修改的所有檔案:
find . -mtime +1
預設情況下,-mtime、-atime 和 -ctime 指的是最近 24 小時。但是,如果它們前面加上了開始時間選項,則 24 小時的周期將從當日的開始時間算起。您還可以使用 mmin、amin 和 cmin 尋找在不到 1 小時的時間內變化了的時間戳記。
如果您在登入到您的帳戶後立即運行以下命令,您將找到在不到 1 分鐘以前讀取的所有檔案:
find . -amin -1 ./.bashrc /.bash_history ./.xauthj5FCx1
應該注意的是,使用 find 命令尋找檔案本身將更改該檔案的訪問時間作為其中繼資料的一部分。
您還可以使用 -newer、-anewer 和 –cnewer 選項尋找已修改或訪問過的檔案與特定的檔案比較。這類似於 -mtime、-atime 和 –ctime。
• -newer 指內容最近被修改的檔案 • -anewer 指最近被讀取過的檔案 • -cnewer 指狀態最近發生變化的檔案
要尋找您的主目錄中自上一個 tar 檔案以來以某種方式編輯過的所有檔案,使用以下命令:
find . -newer  backup.tar.gz
按大小尋找檔案
-size 選項尋找滿足指定的大小條件的檔案。要尋找所有大於 5MB 的使用者檔案,使用
find / -size  +5000000c 2> /dev/null /var/log/lastlog /var/log/cups/access_log.4 /var/spool/mail/bluher
結尾的“c”以位元組為單位報告我們的結果。預設情況下,find 以 512 位元組塊的數量報告大小。如果我們將“c”替換為“k”,我們還會看到以KB的數量報告的結果,如果使用“w”,則會看到以兩位元組字的數量報告的結果。
-size 選項經常用於搜尋所有零位元組檔案並將它們移至 /tmp/zerobyte 檔案夾。以下命令恰好可以完成這一任務:
find test -type f  -size 0 -exec mv {} /tmp/zerobyte \;
-exec 操作允許 find 在它遇到的檔案上執行任何 shell 命令。在本文的後面部分,您將看到其用法的更多樣本。大括弧允許移動每個空檔案。
選項 -empty 還可用於尋找空檔案:
find test -empty        test/foo test/test
按許可權和所有者尋找
要監視您的系統安全離不開 find 命令。您可以使用符號或八進位標記法尋找面向廣大使用者開放的檔案,如下所示:
find . -type f  -perm a=rwx -exec ls -l {} \;
或者
find . -type f  -perm 777 -exec ls -l {} \; -rwxrwxrwx 1 bluher  users 0 May 24 14:14 ./test.txt
在這一部分中,在上面和下面的命令中,我們使用了 -exec ls -l 操作,因此,您可以看到返回的檔案的實際許可權。以下命令將尋找可由“other”和組寫入的檔案:
find plsql -type f  -perm -ug=rw -exec ls -l {} \; 2>/dev/null
或者
find plsql -type f  -perm -220 -exec ls -l {} \; 2>/dev/null -rw-rw-rw- 1 bluher users 4303  Jun  7   2004 plsql/FORALLSample/doc/otn_new.css -rw-rw-rw- 1 bluher users 10286 Jan  12  2005  plsql/FORALLSample/doc/readme.html -rw-rw-rw- 1 bluher users 22647 Jan  12  2005  plsql/FORALLSample/src/config.sql ..
下一個命令將尋找由使用者、組或二者共同寫入的檔案: 
find plsql -type f  -perm /ug=rw -exec ls -l {} \; 2>/dev/null, or, find plsql -type f  -perm /220 -exec ls -l {} \; 2>/dev/null -rw-r--r-- 1 bluher users 21473  May  3 16:02 plsql/regexpvalidate.zip -rw-rw-rw- 1 bluher users 4303  Jun  7   2004 plsql/FORALLSample/doc/otn_new.css -rw-rw-rw- 1 bluher users 10286 Jan  12  2005  plsql/FORALLSample/doc/readme.html -rw-rw-rw- 1 bluher users 22647 Jan  12  2005  plsql/FORALLSample/src/config.sql
您可能會看到以下命令在 Web 和較早的手冊中引用過:
find . -perm +220  -exec ls -l {} \; 2> /dev/null
+ 符號的作用與 / 符號相同,但是現在新版 GNU findutils 中不支援使用該符號。
要尋找您的系統上所有人都可以寫入的所有檔案,使用以下命令:
find / -wholename  '/proc' -prune  -o  -type f -perm -0002 -exec ls -l {} \; -rw-rw-rw- 1 bluher users 4303  Jun  7   2004/home/bluher/plsql/FORALLSample/doc/otn_new.css -rw-rw-rw- 1 bluher users 10286 Jan  12  2005  /home/bluher/plsql/FORALLSample/doc/readme.html ...
第 4 個許可權將在稍後進行討論,但最後一個欄位中的“2”是檔案許可權中的“other”欄位,也稱為寫入位。我們在許可權模式 0002 前面使用了破折號,以指明我們希望看到為 other 設定了寫入權限的檔案,無論其他使用權限設定為什麼。
上述命令還引入了三個新概念。針對檔案模式“/proc”使用 -wholename 測試,如果該模式已找到,-prune 可防止 find 下到該目錄中。布爾類型“-o”使 find 可以針對其他目錄處理該命令的其餘部分。由於每個運算式之間有一個假設的隱式 and 運算子 (-a),因此,如果左側的運算式計算結果為 false,and 之後的運算式將不進行計算;因此需要 -o 運算子。Find 還支援布爾類型 -not、!,就像使用括弧強行優先一樣。
系統管理員經常使用 find 通過使用者或組的名稱或 ID 搜尋特定使用者或組的常規檔案:
[root] $  find / -type f -user bluher -exec ls -ls {}  \;
下面是這樣一個命令的高度精簡的輸出樣本:
4 -rw-r--r-- 1 bluher users 48  May  1 03:09  /home/bluher/public_html/.directory 4 -rw-r--r-- 1 bluher users 925  May  1 03:09 /home/bluher/.profile
您還可以使用 find 按組尋找檔案:
[root] $ find /  -type f -group users
find / -type d -gid  100
該命令將列出由 ID 為 100 的組擁有的目錄。要找到相應的 uid 或 gid,您可以針對 /etc/passwd 或 /etc/group 檔案運行 more 或 cat 命令。
除了尋找特定已知使用者和組的檔案外,您還會發現它對於尋找沒有這些資訊的檔案也很有用。下一個命令將識別未列在 /etc/passwd 或 /etc/group 檔案中的檔案:
find / -nouser -o  -nogroup
上述命令可能不會在您的系統上產生實際的結果。但是,它可用於識別或許在經常移動後沒有使用者或組的檔案。
好了,現在我們可以解決本部分開始時提到的格外重要的許可權了。
SGID 和 SUID 是特殊存取權限標誌,可以分配給基於 UNIX 的作業系統上的檔案和目錄。設定它們是為了允許訪問電腦系統的普通使用者使用臨時較高的權限執行二進位可執行檔。
find /  \( -perm -2000 -o -perm -4000 \) -ls 167901   12 -rwsr-xr-x   1 root     root         9340 Jun 16  2006 /usr/bin/rsh 167334   12 -rwxr-sr-x   1 root     tty         10532 May  4  2007 /usr/bin/wall
在上述命令中,您可以看到轉義括弧的使用。您還可以看到許可權的不同。第一個檔案設定了 SGID 許可權,第二個檔案設定了 SUID 許可權。上述命令中的最後的操作與帶 -exec ls -dils 操作的 find 效果類似。 控制 find
與 Linux 中的許多命令不同,find 不需要 -r 或 -R 選項即可下到子目錄中。它預設情況下就這樣操作。但是,有時您可能希望限制這一行為。因此,選項 -depth、-maxdepth 和 -mindepth 以及操作 -prune 就派上用場了。
我們已經看到了 -prune 是多麼有用,下面讓我們來看看 -depth、-maxdepth 和 -mindepth 選項。
-maxdepth 和 -mindepth 選項允許您指定您希望 find 搜尋深入到分類樹的哪一層級。如果您希望 find 只在目錄的一個層級中尋找,您可以使用 maxdepth 選項。
通過運行以下命令在分類樹的前三個層級中尋找記錄檔,您可以看到 -maxdepth 的效果。使用該選項較之不使用該選項所產生的輸出要少得多。
find / -maxdepth 3  -name "*log"
您還可以讓 find 在至少下至分類樹三個層級的目錄中尋找:
find / -mindepth 3  -name "*log"
-depth 選項確保先在一個目錄中進行尋找,然後才在其子目錄中進行尋找。以下命令提供了一個樣本:
find -name "*test*" -depth ./test/test ./test ./localbin/test ./localbin/test_shell_var ./localbin/test.txt ./test2/test/test ./test2/test ./test2
find 世界
我們已經看過了 find 命令的一些更加有用以及有點難懂的功能,但是 find 還可以執行更多的任務。例如,有多個選項可以使 find 與較低的 UNIX 版本和其他動作系統相相容並允許您執行列印輸出到多個檔案等操作。閱讀本文後,您現在已經有了理解 find 參考指南的背景,我鼓勵您深入研究這一強大、有用的工具。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.