2013-10-18 74 views
3

在我的程序(在Mac OS X上)中,我使用以下代碼打開了該文件。打開讀取和寫入的文件可以取消關聯

int fd; 
fd = open(filename, O_RDWR); 

計劃要刪除的文件如下:

unlink(filename); 

在我的情況,我有被打開,刪除相同的文件。我觀察到以下內容:

  1. 打開文件後,我可以使用此程序甚至通過使用rm命令將其刪除。
  2. 刪除文件後,讀取和寫入操作對文件沒有任何問題。

我想知道背後的原因。如何防止rm命令或unlink(2)系統調用刪除正在打開的文件?

+1

打開這不就是'取消鏈接的預期行爲(2)'?你檢查過文件嗎? 「如果 一個或多個進程在最後一個鏈接被刪除時打開文件,鏈接將被刪除,但文件的刪除將被延遲,直到所有對該文件的引用都被關閉。」 –

+0

@CarlNorum:我檢查了取消鏈接(2)。這是預期的行爲。但是爲什麼unlink(2)之後的讀寫操作成功了? – doptimusprime

+0

就像文檔說的那樣,文件在引用關閉之前不會被刪除。該文件仍然存在,所以'read'和'write'應該繼續工作,對吧? –

回答

1

這是UNIX系統中的正常情況。當你rm或取消鏈接一個打開的文件。 UNIX系統只是標記一個標誌,並不會真正刪除該文件的欺騙。直到文件關閉。它會在文件系統中真正刪除。

它可以幫助守護進程正常工作。

+0

感謝您提供推理。如何防止'unlink(2)'和'rm'刪除打開的文件? – doptimusprime

+1

使用chmod和chown限制用戶和組寫入文件 – Chair

6

您不能阻止unlink(2)取消鏈接有權取消鏈接的文件(即,它具有對目錄的寫入訪問權限)。

unlink不叫unlink因爲沒有人能想到一個更好的名字。這就是所謂的,因爲它就是這樣做的;它將該文件從目錄中取消鏈接。 (一個目錄只是一個鏈接集合,即它將名稱與相應數據的位置關聯起來。)它不會刪除文件;當文件系統不再有任何鏈接時,該文件將被文件系統垃圾收集。

打開文件描述符不是保持文件鏈接的唯一方法。另一種很常見的方法是使用link(1)命令,而不使用-s選項。這會創建「硬」鏈接。如果一個文件有多個硬鏈接,那麼刪除其中一個鏈接(使用unlink(2))就是這樣 - 它刪除了其中一個鏈接。

rm命令有一個可能更令人困惑的名字,但它也只刪除,而不是文件。只要有人鏈接到該文件,該文件就存在,包括正在運行的進程。

+0

+1,但建議進行小的編輯。在最後一段中,將「刪除文件的名稱」更改爲「刪除文件的一個名稱」(或類似的東西)。這應該有助於說明路徑名不是文件,並且任何給定的文件可能有多個指向它的路徑。 (很難避免使用「link」而不是「refer」這個詞,不清楚哪一個更清楚。) –

+0

@WilliamPursell:夠公平的。小編輯。 – rici

3

首先,rm命令調用unlink(2)

然後,斷開鏈接打開的文件是做在Linux或其它Unix系統(例如MacOSX的)是很正常的事情。這是獲取臨時文件的規範方式(如tmpfile(3)可能)。

您應該瞭解inodes是什麼,並意識到文件不是它的名稱或文件路徑,而是本質上是一個inode。一個文件可以包含零個,一個或多個文件路徑或名稱(如果所有名稱都位於同一文件系統中,則可以使用系統調用添加更多內容)。目錄條目將名稱與inode關聯。

因此沒有(POSIX便攜式)禁止沒有任何名稱的打開ed文件的I/O。 對於某些打開的文件,內核有其參考計數器到其inode,並保持該inode,直到所有進程open(2) - 它做了close(2)它或已終止。

1

A 鏈接是一個與某個文件關聯的名稱(一個文件基本上是unamed)。請注意,文件可能具有不同的名稱(請嘗試ln)。

unlink()將此關聯之一移除到文件。如果您刪除了文件的最後一個鏈接,這隻會使您無法通過名稱訪問該文件。 但是,這並不意味着該文件是不可用的,因爲文件可能已被打開,並且他目前正被某些應用程序讀取/寫入。

一個文件,當且僅當刪除: - 有它 沒有聯繫 - 它目前不被任何應用程序