rm命令弱爆了!你了解嗎?
大家好,我是良許。
創(chuàng)建、刪除和修改文件是用戶在 Linux 系統(tǒng)中執(zhí)行的非常常見操作。大家都知道,在 Linux 系統(tǒng)里使用 rm 命令刪除單個(gè)文件時(shí),幾乎一瞬間就完成了。但是如果文件數(shù)量很大,那么刪除操作就需要很長時(shí)間才能完成。
你有沒想過,刪除 50 萬個(gè)小文件,需要花費(fèi)多少時(shí)間?
我寫這篇文章的目的,是為了找出在 Linux 中刪除巨量文件的最快方法。通過測試發(fā)現(xiàn),rm 命令簡直弱爆了!
我們將從一些簡單的文件刪除方法開始,然后比較不同方法完成文件刪除任務(wù)的速度??纯茨姆N方式刪除速度最快。
1. 文件刪除的幾種方式
在 Linux 系統(tǒng)中刪除文件,最常用的命令就是 rm 命令。這個(gè)命令相信大家都已經(jīng)很熟悉了,我們來簡單回顧一些 rm 命令的例子。
- $ rm -f testfile
-f 選項(xiàng)在上面的命令中,表示將在不要求確認(rèn)的情況下強(qiáng)行刪除文件。
- $ rm -rf testdirectory
這個(gè)命令將刪除名為 testdirectory 的目錄以及該目錄中的所有內(nèi)容(使用的 -r 選項(xiàng)是遞歸刪除文件)。
而刪除目錄,我們還有另一個(gè)命令,那就是 rmdir ,但是它只有在目錄為空時(shí)才會(huì)刪除該目錄。
- $ rmdir testdirectory
現(xiàn)在我們看看在 Linux 中刪除文件的一些其它不同方法。
我最喜歡的方法之一是使用 find 命令,再進(jìn)行刪除操作。find 命令是一個(gè)非常方便的工具,可用于根據(jù)文件的類型、大小、創(chuàng)建日期、修改日期和更多不同的條件來搜索文件。
我們來看一個(gè) find 命令使用 -exec 來調(diào)用 rm 命令的例子。
- $ find /test -type f -exec rm {} \;
上述命令將刪除 /test 目錄中的所有文件。首先 find 命令將查找目錄中的所有文件,然后對(duì)于每個(gè)搜索結(jié)果,它會(huì)執(zhí)行 rm 命令。
我們再看看可以與 find 命令一起使用的一些不同方法來刪除文件。
- $ find /test -mtime +7 -exec rm {} \;
在上述示例中,find 命令將搜索 /test 目錄中 7 天前修改過的所有文件,然后刪除每個(gè)文件。
- $ find /test -size +7M -exec rm {} \;
上述示例中,將搜索目錄 /test 目錄中所有大于 7M 的文件,然后再刪除它們。
在以上我們列出來的所有 find 命令示例中,都會(huì)為找到的每個(gè)文件調(diào)用 rm 命令。例如,在上面的最后一個(gè) find 命令中,如果結(jié)果中有 50 個(gè)大于 7M 的文件,那么將調(diào)用 50 次 rm 命令刪除文件。而這樣的操作將需要花費(fèi)更長的時(shí)間。
除了在 find 中借助 -exec 參數(shù)調(diào)用 rm 命令外,還有一個(gè)更好的選擇,那就是使用 -delete 選項(xiàng)。比如:
- $ find /test -size +7M -delete
達(dá)到的效果與上一條命令一樣。
2. 刪除巨量文件時(shí)用什么命令最快?
話不多說,我們直接上測試。
首先借助一個(gè)簡單的 bash for 循環(huán)創(chuàng)建 50 萬個(gè)文件。
- $ for i in $(seq 1 500000); do echo testing >> $i.txt; done
上述命令中,將在當(dāng)前工作目錄中創(chuàng)建 50 萬個(gè) txt 文件,名稱從 1.txt 到 500000.txt,每個(gè)文件都包含 testing 的文本內(nèi)容,因此文件大小至少在幾千字節(jié)的范圍。
在創(chuàng)建了 50 萬個(gè)文件后,我們將嘗試使用多方式來刪除它們,看看哪種方式刪除巨量文件速度最快。
Round 1:rm 命令
首先讓我們使用簡單的 rm 命令,同時(shí)我們使用 time 命令來計(jì)時(shí)。
- $ time rm -f *
- -bash: /bin/rm: Argument list too long
- real 0m11.126s
- user 0m9.673s
- sys 0m1.278s
我們可以看到 rm 命令的執(zhí)行結(jié)果是 Argument list too long ,這意味著該命令沒有完成刪除,因?yàn)榻o rm 命令的文件數(shù)量太大而無法完成,所以它直接就躺平罷工了。
不要注意 time 命令顯示的時(shí)間,因?yàn)?rm 命令沒有完成它的操作,time 命令只管顯示你命令執(zhí)行了多長時(shí)間,而不關(guān)心命令的最終結(jié)果。
Round 2:使用 -exec 參數(shù)的 find 命令
現(xiàn)在讓我們使用我們之前看到的帶有 -exec 參數(shù)的 find 命令。
- $ time find ./ -type f -exec rm {} \;
- real 14m51.735s
- user 2m24.330s
- sys 9m48.743s
從我們使用 time 命令得到的輸出可以看出,從單個(gè)目錄中刪除 50 萬個(gè)文件需要 14 分 51 秒。這是相當(dāng)長的時(shí)間,因?yàn)閷?duì)于每個(gè)文件,都會(huì)執(zhí)行一個(gè)單獨(dú)的 rm 命令,直到刪除所有文件。
Round 3:使用 -delete 參數(shù)的 find 命令
現(xiàn)在讓我們通過在 find 命令中使用 -delete 選項(xiàng)來測試消耗的時(shí)間。
- $ time find ./ -type f -delete
- real 5m11.937s
- user 0m1.259s
- sys 0m28.441s
刪除速度大大提高,只用了 5 分 11 秒!當(dāng)你在 Linux 中刪除數(shù)百萬個(gè)文件時(shí),這是速度的驚人改進(jìn)。
Round 4:Perl 語言
現(xiàn)在讓我們看看使用 Perl 語言刪除文件是如何工作的,以及它與我們之前看到的其他刪除方式相比的速度。
- $ time perl -e 'for(<*>){((stat)[9]<(unlink))}'
- real 1m0.488s
- user 0m7.023s
- sys 0m27.403s
從結(jié)果可以看出,Perl 只用了大約 1 分鐘就刪除了該目錄中的 50 萬個(gè)文件,與我們之前看到的其他 find 命令和 rm 命令相比,這個(gè)速度非常之快!
但是,如果您有興趣在使用 Perl 時(shí)用到更復(fù)雜的選項(xiàng),則需要對(duì) Perl 正則表達(dá)式有一定的了解。
Round 5:rsync 命令
還有一種較少使用且鮮為人知的方法可用于刪除文件夾內(nèi)的大量文件,這種方法正是我們著名的工具 rsync ,它的基本用法是用于在 Linux 中的兩個(gè)本地和遠(yuǎn)程位置之間傳輸和同步文件。
現(xiàn)在我們來看看如何使用 rsync 命令的來刪除文件夾內(nèi)所有文件。其實(shí)很簡單,我們可以通過將具有大量文件的目標(biāo)目錄與空目錄進(jìn)行同步來實(shí)現(xiàn)刪除的操作。
在我們的例子中, /test 目錄(目標(biāo)目錄)有 50 萬個(gè)文件,我們再創(chuàng)建一個(gè)名為 blanktest 的空目錄(源目錄)?,F(xiàn)在,我們將在 rsync 命令中使用 -delete 選項(xiàng),這將刪除目標(biāo)目錄中的所有源目錄中不存在文件。
- $ time rsync -a --delete blanktest/ test/
- real 2m52.502s
- user 0m2.772s
- sys 0m32.649s
可以看到,僅用 2 分鐘 52 秒就完成刪除。
因此與 find 命令相比,如果您想清空包含數(shù)百萬個(gè)文件的目錄,使用 rsync 命令會(huì)更好。
3. 小結(jié)
下表總結(jié)了 Linux 中采用不同方式刪除 50 萬個(gè)文件的速度,方便大家參考。
命令 | 花費(fèi)時(shí)間 |
---|---|
rm 命令 | 無法刪除大量文件 |
使用 -exec 參數(shù)的 find 命令 | 14 分 51 秒 |
使用 -delete 參數(shù)的 find 命令 | 5 分 11 秒 |
Perl | 1 分鐘 |
rsync 命令 | 2 分 52 秒 |