是否获得ROBOCOPY返回“正确的”退出代码?


121

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

我将ROBOCOPY用作TeamCity构建配置的一部分,而不得不添加一个步骤以使ROBOCOPY的退出代码保持沉默对我来说似乎很愚蠢。

基本上,我添加了以下内容:

EXIT /B 0

到正在运行的脚本。

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

基本上,我希望成功代码的退出代码为0,失败代码为非零,而不是ROBOCOPY现在返回的位掩码。

或者,如果我不能这样做,是否有简单的批处理命令序列可以将ROBOCOPY的位掩码转换为相似的值?


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

Answers:


47

按照这里,Robocopy具有以下退出代码位,这些位组成退出代码:

0×10严重错误。Robocopy没有复制任何文件。这可能是使用错误,也可能是由于对源目录或目标目录的访问权限不足而导致的错误。

0×08无法复制某些文件或目录(发生复制错误并且超出了重试限制)。进一步检查这些错误。

0×04检测到一些不匹配的文件或目录。检查输出日志。客房清洁可能是必要的。

0×02检测到某些Extra文件或目录。检查输出日志。可能需要一些客房清洁服务。

0×01一个或多个文件已成功复制(即,新文件已到达)。

0×00没有发生错误,也没有复制。源目录树和目标目录树完全同步。

只需添加if / else语句,EXIT /B 0当返回值为1或可能为0时,EXIT /B 1否则添加。即使文件已被复制,还是有一些错误需要手动干预。


107

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

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

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

对于Teamcity部署(不仅是Teamcity),键入:IF %ERRORLEVEL% LEQ 3 set errorlevel=0并在下一行:(if %errorlevel% neq 0 exit /b %errorlevel%如果批处理文件由多个操作组成,不仅是robocopy)很有用
DaoCacao 2012年

6
在TeamCity中,您应该ERRORLEVEL使用双%% 转义,例如:%% ERRORLEVEL %%。否则,它将其视为TeamCity构建参数。
Yan Sklyarenko 2013年

2
怎么^&办?ss64说逃脱,但在我看来,它不应该逃脱?
mlhDev


13

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

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

8

我用这个:

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

8

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

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

因此,错误级别1和3均指示文件复制成功且没有错误。错误级别0和2也表示目标是最新的,没有文件被复制。

为了简单备份,我提出了以下建议:

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

如果错误级别8 echo All不好-备份不完整且已完成

如果错误级别4 echo All不好-某些文件不匹配并且转到完成

如果错误级别3 echo备份成功完成并且转到完成

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

如果错误级别1 echo备份成功完成并且转到完成

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

我选择不打扰“额外”文件。

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


6

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

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

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

2

对于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

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

1

在gitlab ci之前添加cmd / c。

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

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


0

此处的示例说明如何将完成的文件从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 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.