《最暴力的 rm -rf 命令居然刪除目錄失敗了!為什么?》要點:
本文介紹了最暴力的 rm -rf 命令居然刪除目錄失敗了!為什么?,希望對您有用。如果有疑問,可以聯系我們。
當我們在Linux系統中卸載軟件或清理數據時,經常會使用rm -rf命令去刪除某個目錄,例如刪除/tmp/tektea目錄:
[code lang=”shell”]# rm -rf /tm/tektea[/code]
rm命令的-r和-f這兩個參數的man含義如下:
-r, -R, –recursive
remove directories and their contents recursively-f, –force
ignore nonexistent files, never prompt
所以-r和-f分別表示可遞歸刪除目錄和強制刪除文件,組合起來就是我們在Linux系統中所熟知的、最暴力的強制刪除某個目錄的命令了,即便目錄下文件正在被讀寫,也依然會干干凈凈的刪除掉該目錄,因為有-f參數,聽起來合情合理.但你現在已經看了本文的標題,你開始迷惑了吧?
沒關系,下面我們通過一些測試來驗證下這個暴力的 rm -rf 命令,看看它是不是真的那么生猛,可以破壞一切目錄.
用例1:使用cp命令持續往/tmp/tektea目錄下拷貝文件,然后rm -rf /tmp/tektea,測試代碼如下
[code lang=”shell”]# cat test1.sh
#!/bin/bash
i=1
while true
do
cp /tmp/testfile /tmp/tektea/$i
let i++
done
# cat /tmp/testfile
hi[/code]
驗證結果:執行bash test1.sh后,rm -rf /tmp/tektea刪除成功.
用例2:使用dd命令持續往/tmp/tektea目錄下寫文件,然后rm -rf /tmp/tektea,測試代碼如下
[code lang=”shell”]# cat test2.sh
#!/bin/bash
while true
do
dd if=/dev/zero of=/tmp/tektea/ddfile bs=1024 count=1000000000
let i++
done[/code]
驗證結果:執行bash test2.sh后,rm -rf /tmp/tektea刪除成功.
用例3:使用echo命令持續往/tmp/tektea目錄下的文件寫數據,然后rm -rf /tmp/tektea,測試代碼如下
[code lang=”shell”]# cat test3.sh
#!/bin/bash
while true
do
echo hi >>/tmp/tektea/echofile
done[/code]
驗證結果:執行bash test3.sh后,rm -rf /tmp/tektea刪除失敗,且有以下報錯:
# rm -rf /tmp/tektea/
rm: cannot remove `/tmp/tektea’: Directory not empty
通過上面的驗證,首先我們可以得出這條結論:使用rm -rf命令刪除目錄時,如果該目錄下的文件正在被寫入,那么會存在刪除失敗的可能.
那么,以上三個用例都是在往/tmp/tektea目錄寫入數據,為什么僅僅是第三個場景會失敗呢?
各種跡象都把根因指向到了 rm 命令(有興趣的朋友可以下載Linux中rm命令的源碼走讀下),rm命令在-r -f強制刪除目錄時,其邏輯是這樣的:
1)從被刪除目錄的最里層遞歸刪除文件;
2)當最里層目錄A的文件被刪除完以后,再刪除該層文件夾A;
3)在刪除文件夾A前,再檢查目錄A下是否還有文件,如果有則報錯Directory not empty(編外:注意這里了)
現在再來回答這個問題——“為什么僅僅是第三個場景會失敗呢?”,不過在回答前,我先給大家展示兩個數據:
1. 用例1使用cp往/tmp/tektea目錄拷貝數據,15秒大約生成了8600個文件,每秒約573文件,相當于每秒573次寫入
2. 用例3使用echo往/tmp/tektea/echofile寫數據,15秒大約在echofile中寫入了59萬行,每秒約40000次寫入
所以結合rm的實現和幾個用例差異可以清楚的知道——在刪除某個目錄時,若有進程往該目錄寫入數據,則需要先停止該進程的服務(或kill掉該進程),所以我們的一些Shell代碼在卸載或刪除目錄時就存在失敗的可能.
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/4607.html