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