是否可以要求ROBOCOPY退出并显示指示成功或失败的退出代码?

我正在将ROBOCOPY用作TeamCity构建配置的一部分,并且必须添加一个步骤以使退出代码静音

基本上,我已经添加了它:

EXIT /B 0


到正在运行的脚本中。

但是,这当然掩盖了ROBOCOPY会返回的任何实际问题。

基本上,我希望对于成功,退出代码为0,对于失败,退出代码为非零,而不是位-mask表示ROBOCOPY现在返回。

或者,如果我不知道,是否存在简单的批处理命令序列,可以将ROBOCOPY的位掩码转换为相似的值?

评论

还应注意,前8个退出代码(0-7)显然不是错误状态:stackoverflow.com/questions/16533843/psake-and-robocopy-failing

#1 楼

如此处所示,Robocopy具有以下组成退出代码的退出代码位:

0×10严重错误。 Robocopy没有复制任何文件。这既可能是使用错误,也可能是由于对源目录或目标目录的访问权限不足而导致的错误。
0×08无法复制某些文件或目录(发生复制错误并且超出了重试限制)。进一步检查这些错误。
0×04检测到一些不匹配的文件或目录。检查输出日志。
0×02已检测到一些额外的文件或目录。检查输出日志。
0×01成功复制了一个或多个文件(即,新文件已到达)。
0×00没有发生错误,也没有进行复制。源目录树和目标目录树是完全同步的。只需在返回值是1或可能为0时添加if / else语句EXIT /B 0,否则就添加EXIT /B 1。即使文件可能已被复制,还是有一些错误需要手动干预。

#2 楼

TechNet建议使用这种单行代码将退出代码转换为更传统的退出代码:

(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LEQ 1 exit 0


或者这样可以完全忽略退出代码(即不在乎是否它失败或成功):

(robocopy c:\dirA c:\dirB *.*) ^& exit 0


但是,上述两个命令将在robocopy执行后终止脚本。对于CI构建,这尤其是一个问题。如果要在这种情况下使用robocopy,则需要为不相关的退出代码手动设置错误代码。下面,所有低于8的错误代码都将被重写为完全没有错误,并且如果可能的话,脚本将继续。

(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LSS 8 SET ERRORLEVEL = 0


评论


真好需要在robocopy命令两边加上括号,但使用包装器脚本救了我。

–TheCodeKing
2012年3月2日14:59



我无法将此一类代码用作TeamCity中的命令行构建步骤。我不得不将其移至单独的一行。我还向退出命令添加了/ B参数,尽管我认为这不是必需的。

– MikeWyatt
2012年5月7日17:35

对于Teamcity部署(不仅是Teamcity),键入以下内容很有用:IF%ERRORLEVEL%LEQ 3设置errorlevel = 0并在下一行:如果%errorlevel%neq 0退出/ b%errorlevel%(如果批处理文件由多个操作,而不仅仅是robocopy),因为OK代码小于3。ss64.com/nt/robocopy-exit.html

–道可可
2012-12-11 13:23



在TeamCity中,应使用双%%来使ERRORLEVEL转义,例如:%% ERRORLEVEL %%。否则,它将其视为TeamCity构建参数。

– Yan Sklyarenko
2013年9月27日在7:09

^&是做什么的? ss64说转义了,但是在我看来,它不应该转义吗?

– mlhDev
17年5月10日在13:40

#3 楼

从Jenkins运行它需要( )/B。如果要忽略错误级别1,2,3,4:

(robocopy XXX YYY) ^& IF %ERRORLEVEL% LEQ 4 exit /B 0


评论


LSS 8可能更好:)

–伊凡
17年7月16日在16:51

#4 楼

在此页面上,您可以将一个部分添加到批处理文件中,该部分使用错误代码列表来输出错误并运行代码的不同部分:

if %ERRORLEVEL% EQU 16 echo ***FATAL ERROR*** & goto end
if %ERRORLEVEL% EQU 15 echo OKCOPY + FAIL + MISMATCHES + XTRA & goto end
if %ERRORLEVEL% EQU 14 echo FAIL + MISMATCHES + XTRA & goto end
if %ERRORLEVEL% EQU 13 echo OKCOPY + FAIL + MISMATCHES & goto end
if %ERRORLEVEL% EQU 12 echo FAIL + MISMATCHES& goto end
if %ERRORLEVEL% EQU 11 echo OKCOPY + FAIL + XTRA & goto end
if %ERRORLEVEL% EQU 10 echo FAIL + XTRA & goto end
if %ERRORLEVEL% EQU 9 echo OKCOPY + FAIL & goto end
if %ERRORLEVEL% EQU 8 echo FAIL & goto end
if %ERRORLEVEL% EQU 7 echo OKCOPY + MISMATCHES + XTRA & goto end
if %ERRORLEVEL% EQU 6 echo MISMATCHES + XTRA & goto end
if %ERRORLEVEL% EQU 5 echo OKCOPY + MISMATCHES & goto end
if %ERRORLEVEL% EQU 4 echo MISMATCHES & goto end
if %ERRORLEVEL% EQU 3 echo OKCOPY + XTRA & goto end
if %ERRORLEVEL% EQU 2 echo XTRA & goto end
if %ERRORLEVEL% EQU 1 echo OKCOPY & goto end
if %ERRORLEVEL% EQU 0 echo No Change & goto end


:END
REM END OF BATCH FILE


#5 楼

上面的一些海报错过了位掩码的微妙之处。特别是,paradroid错过了错误级别3表示完全成功的复制。

请注意,如果设置了位0x01,则表明即使有其他失败,也已复制了一些文件。因此,任何奇数编号的错误级别始终表示至少已复制了一些文件。
还请注意,位0x02只是表明目标位置上存在某些文件,而源文件中不存在。如果使用/ E开关并且自上次复制以来已从源中删除文件,则会发生这种情况。如果使用/ MIR开关,则不会发生这种情况,因为这应该删除目标位置上的文件以镜像源(但我尚未对此进行测试)。

所以错误级别1和3都表示复制成功的文件没有错误。
错误级别0和2表示目标是最新的,没有文件被复制。

为了简单起见,我提出了以下几点:备份:

如果错误级别16 echo备份失败-请参见上面的原因并转到完成

如果错误级别8 echo一切都不好-备份不完整且goto完成

如果错误级别为4,则echo一切都不好-某些文件不匹配且已完成

如果错误级别为3,则echo成功完成备份并转到了
如果错误级别为2,则echo备份已经是最新的-没有文件已复制且已完成

如果错误级别为1,回显备份已成功完成并已完成

如果错误级别为0,则已备份-最新的-没有已复制文件&goto done
我选择不打扰“额外”文件。

我不知道什么是“不匹配”错误,因为它尚未发生,但为允许以防万一。

#6 楼

我用这个:

robocopy .....
call :REPORT_ERRORLEVEL
goto :EOF

:REPORT_ERRORLEVEL
echo.
if ERRORLEVEL 16 echo ***FATAL ERROR*** & goto :EOF
if ERRORLEVEL 8 echo **FAILED COPIES** & goto :EOF
if ERRORLEVEL 4 echo *MISMATCHES* & goto :EOF
if ERRORLEVEL 2 echo EXTRA FILES & goto :EOF
if ERRORLEVEL 1 echo Copy successful & goto :EOF
if ERRORLEVEL 0 echo –no change– & goto :EOF


#7 楼

我同意来宾约翰(John Guest)的观点-您真的只想指出错误,如果结果实际上是8或更高。

因此将robocopy结果映射到0(成功)或1(失败)结果,适合在SQL Agent作业中使用,我正在使用:

  IF %ERRORLEVEL% LSS 8 EXIT /B 0
  EXIT /B 1


#8 楼

对于TeamCity,我正在使用它,并且效果很好。感谢MikeWyatt,DaoCacao和Yan Sklyarenko的投入。我只需要查看一个完整的工作示例即可帮助直观地查看答案。

(robocopy  .\Artifacts\Fitnesse %FitDestinationFolder% /MIR)
IF %%ERRORLEVEL%% LEQ 3 set errorlevel=0
IF %%ERRORLEVEL%% NEQ 0 EXIT /b %%ERRORLEVEL%%
EXIT 0


评论


我在POST-BUILD事件中使用了类似的robocopy脚本..因此,依赖库被复制到正在使用的.exe应用程序项目中-仅通过控制反转/服务定位器模式进行引用。

– bkwdesign
15年2月12日在18:54

#9 楼

在gitlab ci之前添加cmd / c。

cmd /c (robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LEQ 1 exit 0


否则EXIT 0将在那时关闭CI管道。

评论


我也有gitlab这个问题。 PowerShell将按此处所述将退出代码写入var $ lastexitcode中,因此不再需要使用运算符:(robocopy E:\ test E:\ test1 / MIR); if($ lastexitcode -eq 0){write-host “自动复制成功”} else {write-host $ lastexitcode};

–ThreeCheeseHigh
19年11月13日在8:43

#10 楼

这里是一个有关如何将完成的文件从Visual Studio 2010+复制到另一个文件夹的示例,因为Visual Studio期望良好的副本上的值为0而不是1。

cmd /c (robocopy $(TargetDir) X:$(TargetName) $(TargetFileName) $(TargetFileName).config *.dll *.json *.xml /xx) ^& IF %ERRORLEVEL% LEQ 1 exit 0 


#11 楼

我无法可靠地将具有%ERRORLEVEL%的版本视为失败,所以这是我想到的:

cmd /C (robocopy a b) ^& IF NOT ERRORLEVEL 8 (EXIT 0) ELSE (EXIT 1)

所有失败都得到映射到错误代码1,否则成功的代码为0。

请注意,IF ERRORLEVEL #的意思是“错误级别≥#”,因此IF NOT ERRORLEVEL 8的意思是“错误级别小于8”。

Robocopy的返回码仅在8个或8个以上时指示错误。


任何大于8的值都表示在复制操作过程中至少存在一个故障。