next up previous
Next: 我要如何列出整個目錄樹呢? Up: 初學者可能會問的基本問題 Previous: 我要怎麼刪除以 '-' 字元開頭為檔名的檔案?

我要怎樣才能把檔名當中含有特殊字元的檔案刪除?

如果這個「特殊字元」是 '/',請跳到這題的結尾;如果這個特殊的字元是 一個 ' 或者控制字元或者中文字,請繼續往下讀。

典型的解法是:

        rm -i some*pattern*that*matches*only*the*file*you*want
這樣子的話 rm 會在要刪除符合你給的條件的檔案前,要你確定,不 過若你的 shell 會將每個字元的第八個 bit 變成零,那以中文作檔 名的檔案可能就刪除不掉了!

或是

        rm -ri .
這樣子的話 rm 會刪除目前目錄下的所有檔案,而在刪除一個檔案之 前會問你是否要刪除此檔。不過很不幸的,並非每一個版本的 rm 都 能這麼用。再者,就算能用的話,這麼做的話會把目前所在目錄的所 有子目錄都找進去,可能要用 "chmod a-x" 避免使子目錄無法搜尋才 能避免可怕的後果。要做 "rm -r" 或含有萬用字元的 "rm" 前請先深 呼吸,搞清楚自己是在做什麼!

或者是,

        find . -type f ... -ok rm '{}' \;
"..." 是一堆用以辨識檔案名稱的述詞,譬如在找出一有問的檔案的 inode 為何後,用
        find . -num 12345 -ok rm '{}' \;
或者是
        find . -inum 12345 -ok mv '{}' new-file-name \;
刪除或改名。 選項 "-ok" 是告訴 find 要執行指令前先要求你確認 。若你能確定所下的指令沒有問題,或者怕所要處理檔案有奇怪的字 元印出來會使螢幕亂七八糟,那用選項 "-exec" 就不會先要求你的確 認。

那當檔案名稱裡含有 '/' 時要怎麼辦呢?

這類檔案是很特別的情形,並且只會因為 kernel 的 bug 而發生(通 常是在寫 NFS 的時候,沒有把從遠端機器來的檔案名稱中不合規定的 字元過濾掉)。我們第一件要做的事情就是,試著去瞭解為什麼這個 問題會如此奇怪。

UNIX 的目錄其實就只是單純的檔名和 inode number 的成對組合。 舉例來說,目錄包含了如下的資訊:

filename inode
file1 12345
file2.c 12349
file3 12347

理論上,只有 '/' 和 ' $\backslash$0' 兩個字元不能用在檔案名稱中, 因為它們有以下的特殊用途:
'/'
:用來分隔目錄名稱及檔案名稱。
' $\backslash$0'
:用來當檔名的終結字元。
非常、極端、很不幸的,某些廠商做出來的 NFS 在回應遠端機器的要 求時,會很白痴地造出含有斜線 (/)的檔名。例如,當某人在 Mac 或其他非 Unix 機器透過 NFS 造一個以日期為名稱的檔案到你的  Unix 中。那麼,你的 Unix 目錄看起來可能就會像這個樣子:
filename inode
91/02/07 12357

我們前面所提過的 'find' 或 'rm' 都無法刪除這個檔案,因為這些或 其他的 Unix 程式都會強制把 '/' 當作前述的分隔字元解釋。

其實,任何一般的程式都會試著做 unlink("91/02/07"),而這對  kernel 來說,它的意義是 "unlink 目錄 91 下的子目錄 02 中的檔 案 07,但是,我們並沒有這樣的檔案,我們有的是一個名叫  "91/02/07" 的檔案在目前的目錄中。這是個極細微但極重要的區別。

這時該怎麼辦呢?首先,先回到產生這種亂七八糟檔名的 Mac,試試 看 NFS daemon 要不要讓你改成不含 '/' 的檔名。如果不行,那就得 找你的系統管理者幫忙了。請他試試以下幾種方法之一:

1.
用 "ls -i" 找出檔案的 inode number, umount 掉這個  file system 然後以 "clri" 將這個 inode 清除,然後 祈求 fsck" 的成功。這個作法會刪除這亂七八糟檔名的 檔案。

2.
若還想保存這個檔案的資料,試試以下的做法:

3.
若你有一個叫做 "fsdb" 的程式,那你可以試試看嘍!


next up previous
Next: 我要如何列出整個目錄樹呢? Up: 初學者可能會問的基本問題 Previous: 我要怎麼刪除以 '-' 字元開頭為檔名的檔案?
Tan Koan-Sin
1999-03-02