2015-12-14 46 views
0

正常使用CP -au更新從測試目錄的工作目錄。這通常符合預期,直到在這個未來:複製更新從源到目標目錄發行

[email protected]:~$ echo Update Test 
Update Test 
[email protected]:~$ mkdir /tmp/src 
[email protected]:~$ touch /tmp/src/{b,c,d} 
[email protected]:~$ ls -i /tmp/src/{b,c,d} 
26019 /tmp/src/b 26020 /tmp/src/c 26025 /tmp/src/d 

[email protected]:~$ ln /tmp/src/b /tmp/src/a 
[email protected]:~$ ls -i /tmp/src 
26019 a 26019 b 26020 c 26025 d 

[email protected]:~$ mkdir dst 
[email protected]:~$ cp -a /tmp/src/* dst 

[email protected]:~$ ls -i dst 
26002 a 26002 b 26026 c 26034 d 

[email protected]:~$ ln -f dst/c dst/a 
[email protected]:~$ ls -il dst 
total 0 
26026 -rw-r--r-- 2 guest guest 0 Dec 7 00:00 a 
26002 -rw-r--r-- 1 guest guest 0 Dec 7 00:00 b 
26026 -rw-r--r-- 2 guest guest 0 Dec 7 00:00 c 
26034 -rw-r--r-- 1 guest guest 0 Dec 7 00:00 d 

[email protected]:~$ ls -il /tmp/src/ 
total 0 
26019 -rw-r--r-- 2 guest guest 0 Dec 7 00:00 a 
26019 -rw-r--r-- 2 guest guest 0 Dec 7 00:00 b 
26020 -rw-r--r-- 1 guest guest 0 Dec 7 00:00 c 
26025 -rw-r--r-- 1 guest guest 0 Dec 7 00:00 d 

[email protected]:~$ cp -au /tmp/src/* dst 
[email protected]:~$ ls -il dst 
total 0 
26026 -rw-r--r-- 3 guest guest 0 Dec 7 00:00 a 
26026 -rw-r--r-- 3 guest guest 0 Dec 7 00:00 b 
26026 -rw-r--r-- 3 guest guest 0 Dec 7 00:00 c 
26034 -rw-r--r-- 1 guest guest 0 Dec 7 00:00 d 

Extract from this manual entry for cp:

-u,只有當源文件複製--update比目標文件或當 目標文件是較新的 缺少

目標目錄dst中的文件a,b,c,d不應該被觸摸,因爲它們的時間戳不可能比源代碼等同於src。但是dst/b已被觸及,並且在此基本示例中,cp不符合更新規範。

到目前爲止,我能想到的做副本更新和維護目標目錄硬鏈接結構的唯一辦法是:

  1. 郵編通過目標目錄遞歸
  2. 如果發現鏈接文件,檢查inode針對最初處理的inode的空陣列。
  3. 如果沒有在已處理的inode陣列發現的inode匹配,搜索具有相同的inode所有其他文件。
  4. 在具有相同inode的文件中,確定最早的文件是原始鏈接。
  5. 與源目錄中相同路徑的文件進行比較。如果找到,源文件複製到目標使用CP-UP
  6. 鏈接的所有其他文件與原來相同的inode來更新文件,如果索引節點現在不同了。
  7. 不管與鏈接文件是否被更新,或不能進入其的inode爲經處理的inode陣列。
  8. 重複步驟2-7,直到沒有更多的文件與未處理的鏈接。
  9. 郵編通過源目錄遞歸使用CP-UP如果目標文件不存在,或者沒有鏈接,被忽略在目標目錄鏈接的文件。
+1

您首先創建了一個從'b'到'a'的硬鏈接,然後複製。然後你做了另一個從'c'到'a'的硬鏈接:'a'被硬鏈接到'b',所以它們是同一個文件。第二個副本更新'a','b'和'c',因爲所有3個文件都是相同的文件。 – Kenney

+0

如前所述,第二個副本有一個更新開關,所以人們會期望考慮時間戳,而不是。 – bogomips

+0

是的,我讀過。我做了一些更多的測試(添加了'-v'來查看發生了什麼),甚至沒有'ln -f dst/...'它說'刪除了dst/b'(儘管沒有做任何更改)。後面兩個'cp -a'狀態'刪除了dst/a; src/a - > dst/a; src/b - > dst/b'和'移除dst/b; src/c - > dst/c; src/d - > dst/d',儘管只更新了'a'和'b'。看起來像處理硬鏈接的錯誤。順便說一句,[見這裏](http://unix.stackexchange.com/questions/44247/how-to-copy-directories-with-preserving-hardlinks)的一些替代品。 – Kenney

回答

0

的文件A,B,C,d在目標目錄DST,不應該 被感動,因爲他們的時間戳已經不能在SRC年紀比 其來源的等價物。但是dst/b已經被觸及,並且在這個基本示例cp中的 沒有達到更新規範。

所觀察到的行爲不會更新規範相沖突,因爲該手冊-u說:副本只有當...和文件b一直沒有複製,但一直鏈接,其中cp由於選項-d必須做,暗示-a。(記住,這裏保存意味着保留源,屬性不是那些目的地。)

到目前爲止,我能想到的做副本更新和 保留目標目錄的唯一途徑硬鏈接結構如下: ...

如果你想保持目標的硬鏈接結構,只是做使用選項-d,但如G。 cp -pRu …