您好,登錄后才能下訂單哦!
自己的《Linux系統管理初學者指南--基于CentOS 7.6》已于2019年10月份出版,對于這本書的質量總體上感覺還算滿意,但是限于當時的知識水平,有些地方描述的仍然不是很清楚,所以在講課的過程中也在不斷進行修訂。比如最近在講到find命令的處理動作時,不少學生就提出疑問,因而我對原書中這部分內容進行了重寫,希望再版時可以訂正。
find命令不僅可以查找,還可以對找到的結果進行進一步的處理,這就要用到“處理動作”。
例如,找出/usr/bin目錄中所有的符號鏈接文件。[root@localhost ~]# find /usr/bin -type l
上面這條命令查找出來的結果只顯示文件名,如果我們還想查看每個符號鏈接文件都指向了哪個源文件,就可以在find命令的最后加上處理動作“-ls”。
[root@localhost ~]# find /usr/bin -type l -ls
50346791 0 lrwxrwxrwx 1 root root 3 2月 14 2019 /usr/bin/captoinfo -> tic
需要注意的是,這個處理動作“-ls”屬于是find命令的一部分,而并非是之前所介紹的ls命令,因而無法在處理動作“-ls”之后加上ls命令的各種選項。例如,我們希望找出/etc目錄中所有大小在1MB以上的文件,并人性化顯示其詳細信息,那么執行下面的命令就會報錯。
[root@localhost ~]# find /etc -size +1M -ls -lh
find: 未知的斷言“-lh”
要實現這個需求,就要借助于find命令的另外一個處理動作“-exec”。這個處理動作可以將find命令找到的結果當作文件去處理,在“-exec”的后面要跟上進一步處理所要執行的命令,另外在命令中還需要使用符號“{}”表示find命令查找到的結果,在命令的最后必須添加“ \;”表示命令結束(注意前面有個空格)。
例如,找出/etc目錄中所有大小在1MB以上的文件,并人性化顯示其詳細信息,下面這條命令才是正確的做法。在這條命令中,ls就是之前所介紹的ls命令,我們借助于-exec將find命令找到的結果,以文件的形式傳給ls命令繼續處理。
[root@localhost ~]# find /etc -size +1M -exec ls -lh {} \;
-rw-------. 1 root root 3.8M 11月 3 2018 /etc/selinux/targeted/active/policy.kern
再比如,找出/tmp目錄中所有后綴為“.txt”的文件并將其刪除。[root@localhost ~]# find /tmp -name "*.txt" -exec rm -f {} \;
很多同學在這里會疑惑,為什么這里用管道符“|”(將在2.9.5節介紹)無法實現上面的操作呢?比如我們做下面的測試:
[root@localhost ~]# touch /tmp/{a,b,c}.txt #在/tmp目錄中生成3個測試文件
[root@localhost ~]# find /tmp -name "*.txt" | rm -f #利用管道結合rm刪除
[root@localhost ~]# find /tmp -name "*.txt" #測試文件仍然存在
/tmp/a.txt
/tmp/b.txt
/tmp/c.txt
[root@localhost ~]# find /tmp -name "*.txt" -exec rm -f {} \; #利用exec結合rm刪除
[root@localhost ~]# find /tmp -name "*.txt" #測試文件被成功刪除
處理動作-exec最主要的作用就是可以將find命令找到的結果當成文件去處理,而默認情況下,find命令找到的結果是被當作文本信息去處理的。
怎樣理解上面這段話呢?比如對于執行“find /tmp -name "*.txt"”命令所找到的三個文件:/tmp/a.txt、/tmp/b.txt、/tmp/c.txt,默認情況下find命令只是把符合查找條件的這三個文件找到,并把它們的名字在屏幕上輸出,因而我們在屏幕上所看到的只是三行文本信息。對于文本信息,可以使用之前介紹的文件內容操作命令進行處理,比如用wc命令統計行數,用grep命令進行過濾等。
[root@localhost ~]# find /tmp -name "*.txt" | wc -l #統計find找到的文件數量
3
[root@localhost ~]# find /tmp -name "*.txt" | grep 'a' #對find的結果進行過濾
/tmp/a.txt
對于文本信息,之前介紹的文件和目錄操作命令就無法處理了,比如cp、mv、rm等,因為這些命令所操作的對象必須是文件。此時-exec就可以派上用場,因為它的主要作用就是可以將find命令找到的結果不再看作是文本信息,而是看作文件。因而如果需要對find的結果用文件操作命令進行進一步處理的話,那么就需要結合-exec。
例如,查找/boot目錄下的以“init”開頭的文件,并將其復制到/tmp目錄。[root@localhost ~]# find /boot -name "init*" -exec cp {} /tmp \;
除了-ls和-exec之外,還有一個比較常用的處理動作是-delete,它可以將find找到的結果直接刪除。
例如之前的操作:找出/tmp目錄中所有后綴為“.txt”的文件并將其刪除。其實更為簡便的做法是下面的命令:[root@localhost ~]# find /tmp -name "*.txt" -delete
當在find命令中利用-exec對查找到的結果進行進一步處理時,有時可能會出現問題。這是因為-exec是將find所找到的結果一次性地送給后面的命令進行處理,有時候find可能會找到大量的文件,超出了后面的命令所能處理的參數范圍,這時就會出現溢出錯誤,錯誤信息通常是“參數列太長”或“參數列溢出”,這時就可以使用xargs命令。xargs雖然本身是一個獨立的Linux命令,但通常都是被用來配合find命令使用。通過xargs,可以將find所找到的結果分批次地送給之后的命令進行處理,從而避免出現溢出問題。
xargs命令需要通過管道與find命令配合使用,xargs的命令格式“find ……| xargs commands”。
下面我們先準備一個測試文件。
[root@localhost ~]# mkdir /tmp/pass
[root@localhost ~]# echo "password:123" >> /tmp/pass/test.txt
假設在/tmp目錄中存放了大量的文件,在其中的某個文件里存放了一個密碼,關鍵字為“password”,我們現在希望能夠將這個存放了密碼的文件找出來。
如果利用find命令的-exec選項,可以執行下面的命令:
[root@localhost ~]# find /tmp -type f -exec grep "password" {} \;
password:123
可以發現,雖然通過上面的命令找出了密碼,但并沒有顯示存放該密碼的文件名。下面換做用xargs命令來實現該要求,xargs就可以將關鍵字所在的文件一并顯示出來。
[root@localhost ~]# find /tmp -type f | xargs grep "password"
/tmp/pass/test.txt:password:123
再比如,我們希望將/tmp目錄以及/tmp所有下級子目錄中,文件名以“.txt”作為后綴的文件都復制到/root目錄中。如果用find命令的-exec來實現:[root@localhost ~]# find /tmp -name "*.txt" -exec cp {} /root \;
如果用xargs命令來實現,同樣需要用“{}”來代指find命令查找到的結果,并且需要為xargs命令添加-i選項。[root@localhost ~]# find /tmp -name "*.txt" | xargs -i cp {} /root
通過這幾個實例可以發現,xargs命令與find命令-exec處理動作的功能基本相同,所以如果-exec可以滿足要求,那么就無需使用xargs命令。xargs命令的主要用途在于它可以對find命令找到的結果分批處理,避免出現溢出錯誤。
比如在/etc目錄中一共有2507個普通文件。
[root@localhost ~]# find /etc -type f | wc -l
2507
如果我們希望能找出/etc目錄中所有包含關鍵字“PermitRootLogin”的文件,分別用這兩種方法來實現:
[root@localhost ~]# find /etc -type f -exec grep "PermitRootLogin" {} \;
#PermitRootLogin yes
# the setting of "PermitRootLogin without-password".
[root@localhost ~]# find /etc -type f | xargs grep "PermitRootLogin"
/etc/ssh/sshd_config:#PermitRootLogin yes
/etc/ssh/sshd_config:# the setting of "PermitRootLogin without-password".
可以發現在用-exec的方法實現時,出現了明顯的卡頓,如果數據量再大一些的話,可能就會導致溢出。而用xargs命令來實現,一方面更為快速,另一方面不會出現溢出問題,而且顯示的內容也更為詳細。所以在進行這類操作時,更加推薦使用xargs命令。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。