rm (Unix)
rm,是一個基本的UNIX命令,其名稱源自英文單詞remove的縮寫,用於刪除檔案系統中的檔案、目錄、裝置檔案、符號連結等對象。準確地說,rm移除的指向特定對象的參照。在檔案系統中,這些特定的對象可能有多個參照(例如,兩個不同的檔名可能指向相同的檔案), 只有在一個對象不再有任何參照,並且沒有任何程式還擁有這個檔案的有效控制代碼的時候,這個檔案才會被刪除。
這一機制允許下列出現:某個程式可以建立一個檔案,並立即將此檔案從檔案系統中移除,並將這個檔案佔用的空間作為臨時空間使用。(因為在該程式退出甚至是崩潰的時候,這一檔案佔用的空間會被回收。)
rm命令一般來說並不摧毀檔案數據,因為其目的僅僅在於解除參照。即便檔案已經解除所有的參照,在檔案系統中,被釋放的空間裏可能還會有被刪除檔案的殘留數據。在一些情況下這會帶來安全問題,因此有時加強版的命令會在檔案的最後一個連結斷開之後抹除被刪除檔案的數據。此外,一些程式(例如:shred)可以提供數據抹除能力。
範例
下列命令將名為"foo"的檔案自目錄中移除:
% rm foo
一般而言,rm不產生輸出資訊,其只在錯誤發生的時候才報告錯誤資訊。 如果加上參數 -v,則可以獲得詳細的檔案移除的動作資訊。
有時用戶擔心意外刪除檔案,特別是在使用萬用字元刪除檔案的時候。 這些情況下可以使用 -i參數,使rm在執行每個刪除動作之前都提示用戶確認。
% rm -i foo
remove foo? y
背景
rm 一般在UNIX及其衍生作業系統中出現,而這些系統不提供已被刪除檔案的恢復機制(例如資源回收筒)[1],因此用戶常對rm命令進行一些封裝以避免意外刪除檔案。
也有被稱為undelete的實用工具。如果被刪除檔案原先佔用的部分未被再度利用,這一工具將嘗試恢復檔案的索引以將這一被刪除檔案恢復。
命令參數
rm命令接受的常見參數有:
- -r : 遞歸("recursive"),刪除目錄,在刪除這一目錄前會事先刪除目錄中的內容(避免刪除了目錄而使目錄中的檔案無處存放的問題)
- -i : 互動("interactive"),為每一個刪除操作詢問一次刪除確認。
- -f : 強制("force"),忽視不存在的檔案,無視任何的確認提示。但是若目錄防寫,這一命令無法移除該目錄中的檔案。
利用C shell命令alias或是Bourne shell的功能,rm命令常常被「rm -i」命令覆蓋,這樣可以防止意外的檔案刪除操作。
如果用戶還是想不通過確認而刪除大量的檔案,他們可以手動為命令追加「-f」參數,取消"-i"參數的效果(這是因為加上「-f」參數後,命令變為了「rm -i -f」,而後指定的參數有更高的優先級)。不過這個方法也可能使用戶養成使用萬用字元等危險的習慣,而這一習慣還是會導致意外的檔案刪除。
rm -rf(其他的形式包括: rm -rf /, rm -rf *等)常常在描述UNIX災難的笑話和軼事中出現[2]。 若在根目錄由超級用戶執行 rm -rf 命令,將會導致系統中所有已掛載可寫入檔案系統中所有內容的清除,直到系統自身因為遺失重要檔案或目錄而崩潰或其他致命系統事件,這一命令才會終止。
rm命令常常與xargs命令一起使用,這樣就可以支援給定列表的檔案批次刪除:
xargs rm < filelist
或者,也可以刪除在當前目錄下(包含子目錄)的所有PNG圖檔:
find . -name '*.png' -print0 | xargs -0 rm
權限
一般而言,在大部分檔案系統中,刪除檔案需要檔案所在目錄的寫權限(首先為了進入該目錄,還需要該目錄的執行權限)。(注意:這裏需要的是目錄的執行權限,至於檔案自身是否有寫權限與刪除操作成功與否無關。然而,除非使用-f參數,如果想要刪除防寫檔案,GNU rm將詢問用戶確認。)
使用rm -r
刪除目錄時,必須先遞歸刪除這一目錄中所有的內容。這就要求用戶必須獲得對於目錄(及其子目錄)的讀、寫、執行權限(若目錄非空)。需要讀目錄的權限是因為刪除目錄中的檔案,需要先列出目錄中的內容。這一限制有時導致了奇怪的情況: 因為沒有對一非空目錄的讀權限,這一目錄無法刪除,也無法刪除目錄中的內容。但如果這個目錄是空的,那麼目錄就能被刪除。
若在將要刪除的目錄中的某個檔案設置了sticky bit,那麼這個檔案只能由其所有者刪除。
檔案系統根目錄保護
太陽電腦在2005首次發佈的Solaris 10中,引入了"rm -rf /
"保護。若嘗試執行這一命令,系統將匯報不允許移除根目錄。[3] 不久之後,相同的功能引入了FreeBSD版本的rm
實用工具。如果沒有指定--no-preserve-root
參數,GNU rm
將拒絕執行rm -rf /
。這一參數自2006年發佈的GNU核心工具組(版本 6.4)以來成為了預設設置。
用戶確認
系統管理員、設計人員、用戶常通過建立別名或是使用函數的方法覆蓋rm命令,試圖避免意外刪除檔案:
alias rm="rm -i"
rm () { /bin/rm -i "$@" ; }
這樣處理使rm
對每個要刪除的檔案進行逐個操作確認,用戶通過輸入"Y"或"N"鍵來確認或否認。但是,這導致用戶粗心地在rm命令中使用萬用字元,也導致用戶會交替地按壓y和Enter來不斷確認刪除,而這樣做容易導致用戶確認刪除本想保留的檔案。一些用戶甚至使用"yes | rm files
"命令快速確認檔案刪除。
一種折衷的方法允許用戶只進行一次確認,鼓勵適當使用萬用字元,更容易驗證將要刪除的檔案列表,實現的參考代碼如下:
if [ -n "$PS1" ] ; then
rm ()
{
ls -FCsd "$@"
echo 'remove[ny]? ' | tr -d '\012' ; read
if [ "_$REPLY" = "_y" ]; then
/bin/rm -rf "$@"
else
echo '(cancelled)'
fi
}
fi
需要注意的是這一函數不該製成shell指令碼,這樣可能導致其在搜尋路徑中先於原始的rm命令。
其也不該在非互動的shell中使用,因為這一指令碼可能會中斷批次處理任務。將這一定義封裝在if [ -n "$PS1" ] ; then .... ; fi
中將避免這一錯誤做法。
也有一些第三方封裝可以預防重要檔案被意外刪除,例如"safe-rm"。[4]
參見
參考資料
- ^ How do I "undelete" a file?. [2012-09-29]. (原始內容存檔於2012-10-10).
- ^ Gite, Vivek. Linux/UNIX: Delete a file. Nixcraft. [24 November 2011]. (原始內容存檔於2012-06-24).
- ^ Meddling in the Affairs of Wizards. [2012-09-29]. (原始內容存檔於2011-03-16).
- ^ Safe RM - Protecting You Business Assets. [2020-09-26]. (原始內容存檔於2020-01-18).