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和回車來不斷確認刪除,而這樣做容易導致用戶確認刪除本想保留的文件。一些用戶甚至使用"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).