如何强制 Robocopy 覆盖文件?

Posted

技术标签:

【中文标题】如何强制 Robocopy 覆盖文件?【英文标题】:How do I force Robocopy to overwrite files? 【发布时间】:2017-04-06 06:35:16 【问题描述】:

通常,Robocopy 会忽略 lastwrittendate 和 filesize 相同的文件。我们如何才能摆脱这种设计?我想用 Robocopy 强制覆盖。

我预计 dst\sample.txt 应该写成 test001。 但是这些文件被 Robocopy 识别为相同的文件并且不会被覆盖。 “/IS”选项在这种情况下无效。

New-Item src -itemType Directory
New-Item dst -itemType Directory
New-Item src\sample.txt -itemType File -Value "test001"
New-Item dst\sample.txt -itemType File -Value "test002"
Set-ItemProperty src\sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00"
Set-ItemProperty dst\sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00"

ROBOCOPY.exe src dst /COPYALL /MIR
Get-Content src\sample.txt, dst\sample.txt
> test001
> test002

ROBOCOPY.exe src dst /COPYALL /MIR /IS
Get-Content src\sample.txt, dst\sample.txt
> test001
> test002

【问题讨论】:

【参考方案1】:

来自the documentation:

/is 包含相同的文件。 /it 包括“调整”文件。

“相同文件”是指相同的文件(名称、大小、时间、属性)。 “调整文件”是指名称、大小和时间相同但属性不同的文件。

robocopy src dst sample.txt /is      # copy if attributes are equal
robocopy src dst sample.txt /it      # copy if attributes differ
robocopy src dst sample.txt /is /it  # copy irrespective of attributes

超级用户上的This answer很好地解释了选择参数匹配的文件类型。

话虽如此,我可以重现您描述的行为,但根据我对文档的理解以及测试中生成的输出robocopy,我认为这是一个错误。

PS C:\temp> New-Item src -Type Directory >$null
PS C:\temp> New-Item dst -Type Directory >$null
PS C:\temp> New-Item src\sample.txt -Type File -Value "test001" >$null
PS C:\temp> New-Item dst\sample.txt -Type File -Value "test002" >$null
PS C:\temp> Set-ItemProperty src\sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00"
PS C:\temp> Set-ItemProperty dst\sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00"
PS C:\temp> robocopy src dst sample.txt /is /it /copyall /mir
...
  选项:/S /E /COPYALL /PURGE /MIR /IS /IT /R:1000000 /W:30

-------------------------------------------------- ----------------------------

                           1 C:\temp\src\
            修改 7 sample.txt

-------------------------------------------------- ----------------------------

               总计 复制 跳过不匹配失败的额外内容
    目录:1 0 0 0 0 0
   文件:1 1 0 0 0 0
   字节:7 7 0 0 0 0
...
PS C:\temp> robocopy src dst sample.txt /is /it /copyall /mir
...
  选项:/S /E /COPYALL /PURGE /MIR /IS /IT /R:1000000 /W:30

-------------------------------------------------- ----------------------------

                           1 C:\temp\src\
            同7样例.txt

-------------------------------------------------- ----------------------------

               总计 复制 跳过不匹配失败的额外内容
    目录:1 0 0 0 0 0
   文件:1 1 0 0 0 0
   字节:7 7 0 0 0 0
...
PS C:\temp> 获取内容 .\src\sample.txt
测试001
PS C:\temp> 获取内容 .\dst\sample.txt
test002

该文件被列为已复制,并且由于它成为相同的文件之后第一个robocopy 运行至少时间是同步的。然而,即使根据输出复制了 7 个字节,尽管设置了数据标志(通过/copyall),在这两种情况下都没有实际将数据写入目标文件。如果明确设置数据标志 (/copy:d),行为也不会改变。

我必须修改上次写入时间以获取robocopy 才能实际同步数据。

PS C:\temp> Set-ItemProperty src\sample.txt -Name LastWriteTime -Value (Get-Date)
PS C:\temp> robocopy src dst sample.txt /is /it /copyall /mir
...
  选项:/S /E /COPYALL /PURGE /MIR /IS /IT /R:1000000 /W:30

-------------------------------------------------- ----------------------------

                           1 C:\temp\src\
100% 较新的 7 示例.txt

-------------------------------------------------- ----------------------------

               总计 复制 跳过不匹配失败的额外内容
    目录:1 0 0 0 0 0
   文件:1 1 0 0 0 0
   字节:7 7 0 0 0 0
...
PS C:\temp> 获取内容 .\dst\sample.txt
test001

一个公认的丑陋解决方法是更改​​相同/调整文件的最后写入时间以强制 robocopy 复制数据:

& robocopy src dst /is /it /l /ndl /njh /njs /ns /nc |
  Where-Object  $_.Trim()  |
  ForEach-Object 
    $f = Get-Item $_
    $f.LastWriteTime = $f.LastWriteTime.AddSeconds(1)
  
& robocopy src dst /copyall /mir

切换到xcopy 可能是您的最佳选择:

& xcopy src dst /k/r/e/i/s/c/h/f/o/x/y

【讨论】:

好的。我将使用 xcopy。 我同意,3 年后 /is 开关似乎并没有强制文件再次复制。它说它是复制的(即复制 = 1),但显然不是,因为我正在使用 1GB 进行测试并且它是即时的 刚刚在 Windows Server 2019 上尝试过此操作,robocopy source destn file /is 确实再次复制了该文件。那里是 v10.0.17763,与 Windows 10 1809 附带的版本相同 Windows Server 2019 Robocopy 10.0.17763.1 从本地到本地,按预期覆盖文件。从本地到映射网络驱动器的相同命令,不会发生覆盖。我怀疑 DFS(分布式文件系统)。从本地到映射网络驱动器的 UNC 的相同命令,覆盖不起作用。从本地到另一台开发计算机的 UNC 的相同命令,覆盖按预期工作。我确保共享缓存已打开并再次尝试,覆盖工作。因此,我认为 DFS 是问题或需要使用 /ZB。 为我工作:)【参考方案2】:

我为一个主文件夹执行此操作,其中所有文件夹都位于相应用户的桌面上,可以通过没有适当权限的快捷方式访问,因此即使它在那里,用户也看不到它。所以我用 Robocopy 和参数来用正确的设置覆盖文件:

FOR /F "tokens=*" %G IN ('dir /b') DO robocopy  "\\server02\Folder with shortcut" "\\server02\home\%G\Desktop" /S /A /V /log+:C:\RobocopyShortcut.txt /XF *.url *.mp3 *.hta *.htm *.mht *.js *.IE5 *.css *.temp *.html *.svg *.ocx *.3gp *.opus *.zzzzz *.avi *.bin *.cab *.mp4 *.mov *.mkv *.flv *.tiff *.tif *.asf *.webm *.exe *.dll *.dl_ *.oc_ *.ex_ *.sy_ *.sys *.msi *.inf *.ini *.bmp *.png *.gif *.jpeg *.jpg *.mpg *.db *.wav *.wma *.wmv *.mpeg *.tmp *.old *.vbs *.log *.bat *.cmd *.zip /SEC /IT /ZB /R:0

如您所见,有许多文件类型我设置为忽略(以防万一),只需根据您的需要或您的情况设置它们即可。

它在 Windows Server 2012 上进行了测试,每个开关都记录在 Microsoft 的网站和其他网站上。

【讨论】:

嗨,欢迎来到 SO。我已经编辑了你的答案,试图让它更容易理解,但我不确定这就是你的意思。无论如何,您已经描述了您的场景(我还没有真正理解,抱歉),但是您还没有解释您的命令的作用,而且由于它是一个复杂的命令,因此弄清楚它并非易事。我建议edit 回答您的问题,并至少提供有关此命令的作用和方式的一般描述。此外,您确定要回答最初的问题,即如何强制 Robocopy 覆盖看起来相同的文件?【参考方案3】:

这真的很奇怪,为什么没有人提到 /IM 开关?!我已经在备份工作中使用它很长时间了。但是我刚才尝试用谷歌搜索,即使在MS website 上,我也无法登陆一个说任何关于它的网页!!!!还发现很多用户帖子抱怨同样的问题!!

无论如何.. 要使用 Robocopy 覆盖 EVERYTHING 源或目标中的任何大小或时间,您必须在命令中包含这三个开关 (/IS /IT /IM)

/IS :: Include Same files. (Includes same size files)
/IT :: Include Tweaked files. (Includes same files with different Attributes)
/IM :: Include Modified files (Includes same files with different times).

这是我用来传输几 TeraBytes 的大部分 1GB+ 文件(ISO - 磁盘映像 - 4K 视频)的确切命令:

robocopy B:\Source D:\Destination /E /J /COPYALL /MT:1 /DCOPY:DATE /IS /IT /IM /X /V /NP /LOG:A:\ROBOCOPY.LOG

我为你做了一个小测试..结果如下:

               Total    Copied   Skipped  Mismatch    FAILED    Extras
    Dirs :      1028      1028         0         0         0       169
   Files :      8053      8053         0         0         0         1
   Bytes : 649.666 g 649.666 g         0         0         0   1.707 g
   Times :   2:46:53   0:41:43                       0:00:00   0:41:44


   Speed :           278653398 Bytes/sec.
   Speed :           15944.675 MegaBytes/min.
   Ended : Friday, August 21, 2020 7:34:33 AM

Dest, Disk: WD Gold 6TB(将写入速度与我的结果进行比较)

即使有这些“附加”,也仅用于报告,因为“/X”开关。如您所见,没有任何内容被跳过,所有文件的总数和大小都等于复制的。有时,当我滥用它并在操作过程中多次取消它时,它会显示少量跳过的文件,但即使前两列中的值始终相等。我还通过运行 PowerShell 脚本来确认这一点,该脚本扫描目标中的所有文件并生成所有时间戳的报告。

我使用它的历史中的一些性能提示以及许多测试和麻烦!:

。尽管大多数在线用户建议使用最大线程数“/MT:128”,但这是获得最佳性能的一般技巧...... 请不要使用非常大的“/MT:128”文件 ...这是一个很大的错误,它会在多次运行后显着降低您的驱动器性能..它会产生非常高的碎片,甚至在某些情况下会导致文件系统出现故障,您最终会花宝贵的时间尝试恢复 RAW 分区和所有这些废话。最重要的是,它的执行速度会慢 4-6 倍!!

对于非常大的文件:

    仅使用“一个”线程“/MT:1”|影响: 必须使用“/J”来禁用缓冲。 |影响:高 将“/NP”与“/LOG:file”一起使用,不要通过“/TEE”输出到控制台 |影响:中等。 将“/LOG:file”放在与源或目标不同的驱动器上 |影响:低。

对于常规大文件:

    使用多线程,我不会超过“/MT:4” |影响: 如果目标磁盘的缓存规格较低,请使用“/J”禁用缓冲 |影响:高 &4 同上。

对于数千个小文件:

    发疯 :) 使用多线程,起初我会从 16 开始,然后乘以 2,同时监控磁盘性能。一旦它开始下降,我将回到先前的价值并坚持下去|影响: 不要使用“/J” |影响:高 将“/NP”与“/LOG:file”一起使用,不要通过“/TEE”输出到控制台 |影响:高。 将“/LOG:file”放在与源或目标不同的驱动器上 |影响:高。

【讨论】:

我尝试了一个正常工作的 robocopy 调用,但它抱怨“/IM”无法识别。具体来说,它将“/IM”报告为“无效参数”。

以上是关于如何强制 Robocopy 覆盖文件?的主要内容,如果未能解决你的问题,请参考以下文章

复制文件而不覆盖

如何强制 NLog 覆盖日志文件

如何强制“git pull”覆盖本地文件?

linux 如何不用判断强制cp(复制粘贴覆盖)/bin/cp

强制 SVN 更新/签出覆盖本地文件

linux 如何不用判断强制cp(复制粘贴覆盖)/bin/cp