如何在 Linux 上查詢和刪除損壞的符號連結

2020-06-09 09:51:00

符號連結是指向另一個檔案的 Linux 檔案。如果刪除了被參照的檔案,符號連結會保留,但不會顯示有問題,除非你嘗試使用它。以下是查詢和刪除指向檔案已被刪除的符號連結的簡單方法。

符號連結symbolic link在 Linux 系統上扮演了非常有用的角色。它們可以幫助你記住重要檔案在系統上的位置,使你更容易存取這些檔案,並讓你不必為了更方便存取大檔案而複製它們,從而節省了大量的空間。

什麼是符號連結?

通常稱它們為“符號連結”或“軟連結”,符號連結是非常小的檔案。實際上,符號連結真正包含的是它指向的檔案的名稱,通常包含路徑(相對於當前位置或絕對路徑)。如果有個名為 ref1 的檔案指向名為 /apps/refs/ref-2020 的檔案,那麼 ref1 的長度將為 19 個字元,即使 ref-202 檔案有 2TB。如果指向 ./ref-2020,那麼長度僅為 10 個字元。如果指向 ref-2020,那麼只有 8 個位元組。

如果你執行 vi ref1 之類的命令(其中 ref1 是符號連結的名稱),你將編輯 ref1 指向的檔案,而不是符號連結本身的內容。Linux 系統知道如何使用符號連結,並且可以做正確的事。同樣,如果你使用諸如 catmoreheadtail 之類的命令,那麼將檢視參照檔案的內容。

另一方面,如果刪除符號連結,你將刪除該連結,而不是參照的檔案。再說一次,Linux 知道怎麼做。符號連結使得使用和共用檔案更加容易,僅此而已。

符號連結損壞時

當一個符號連結所指向的檔案從系統中刪除或重新命名時,符號連結將不再起作用。符號連結只不過是儲存在某個特定目錄中的參照而已,它不會隨著指向它的檔案發生變化而更新或刪除。它一直指向被參照的檔案,即使這個檔案早已消失。

如果你嘗試使用指向一個不存在的檔案的符號連結,那麼將出現如下錯誤:

$ tail whassuptail: cannot open 'whassup' for reading: No such file or directory

如果你嘗試存取指向自身的符號連結(是的,奇怪的事情發生了),你將看到類似以下的內容:

$ cat loopycat: loopy: Too many levels of symbolic links$ ls -l loopylrwxrwxrwx 1 shs shs 5 May 28 18:07 loopy -> loopy

而且,如果(上面的)長列表的第一個字母沒有引起你的注意,這表示該檔案是符號連結。rwxrwxrwx 許可權是標準許可權,並不反映符號連結指向的檔案的許可權。

查詢損壞的符號連結

find 命令有一個選項,能讓你找到指向不再存在的檔案的符號連結。此命令列出當前目錄中的符號連結:

$ find . -type l

l (小寫字母 L)告訴 find 命令查詢符號連結。

另一方面,下面的命令在當前目錄中查詢指向不存在的檔案的符號連結:

$ find . -xtype l

為了避免在該命令嘗試查詢你無權檢查的檔案或目錄時發生錯誤,你可以將所有錯誤輸出到 /dev/null,如下所示:

$ find . -xtype l 2>/dev/null

你也可以使用此命令找到損壞的符號連結。它比前面的更長,但做的是同樣的事情:

$ find . -type l ! -exec test -e {} \; -print 2>/dev/null

如何處理損壞的符號連結

除非你知道符號連結參照的檔案會被替換,否則最好的方法是直接刪除損壞的連結。實際上,如果需要,你可以使用一條命令查詢並刪除損壞的符號連結,如:

$ find . -xtype l 2>/dev/null -exec rm {} \;

該命令的 rm {} 部分會變成“刪除檔案”的命令

如果你想將符號連結與不同的檔案相關聯,你必須先刪除該符號連結,然後重新建立它,使其指向新檔案。這是一個例子:

$ rm ref1$ ln -s /apps/data/newfile ref1

總結

符號連結使參照的檔案更易於查詢和使用,但有時它會比那些宣傳去年已經關閉的餐館的路標還過分。find 命令可以幫助你擺脫損壞的符號連結,或者提醒你沒有你可能仍然需要的檔案。