2015-12-14 45 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 …