118

Is it possible to ask ROBOCOPY to exit with an exit code that indicates success or failure?

I am using ROBOCOPY as part of my TeamCity build configurations, and having to add a step to just silence the exit code from ROBOCOPY seems silly to me.

Basically, I have added this:

EXIT /B 0

to the script that is being run.

However, this of course masks any real problems that ROBOCOPY would return.

Basically, I would like to have exit codes of 0 for SUCCESS and non-zero for FAILURE instead of the bit-mask that ROBOCOPY returns now.

Or, if I can't have that, is there a simple sequence of batch commands that would translate the bit-mask of ROBOCOPY to a similar value?

10 Answers 10

46

As per here, Robocopy has the following exit code bits that make up the exit code:

0×10 Serious error. Robocopy did not copy any files. This is either a usage error or an error due to insufficient access privileges on the source or destination directories.

0×08 Some files or directories could not be copied (copy errors occurred and the retry limit was exceeded). Check these errors further.

0×04 Some Mismatched files or directories were detected. Examine the output log. Housekeeping is probably necessary.

0×02 Some Extra files or directories were detected. Examine the output log. Some housekeeping may be needed.

0×01 One or more files were copied successfully (that is, new files have arrived).

0×00 No errors occurred, and no copying was done. The source and destination directory trees are completely synchronized.

Just add if/else statements that EXIT /B 0 when the return value is 1 or maybe 0, and EXIT /B 1 otherwise. Even if files might have been copied, there's something wrong that would need manual intervention.

101

TechNet suggests this one-liner to convert the exit code into a more traditional exit code:

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

Or this to ignore the exit code completely (i.e. don't care if it failed or succeeded):

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

However, both commands above will terminate a script after the robocopy has executed. This is an issue especially for CI builds. If you want to use robocopy in this scenario, you need to set the error code manually for irrelevant exit codes. Below, all error codes below 8 will be rewritten to no error at all, and the script will be continued if possible.

(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LSS 8 SET ERRORLEVEL = 0
  • 8
    Nice. Needs brackets around the robocopy command, but saved me using a wrapper script. – TheCodeKing Mar 2 '12 at 14:59
  • I couldn't get this one-liner to work as a Command Line build step in TeamCity. I had to move it to a separate line. I also added the /B argument to the exit command, although I don't think that was required. – MikeWyatt May 7 '12 at 17:35
  • For Teamcity deployment (and not only Teamcity) it is useful to type: IF %ERRORLEVEL% LEQ 3 set errorlevel=0 and on the next line: if %errorlevel% neq 0 exit /b %errorlevel% (if batch file consists of several operations, not only robocopy), because OK codes are less then 3. ss64.com/nt/robocopy-exit.html – DaoCacao Dec 11 '12 at 13:23
  • 6
    In TeamCity, you should escape the ERRORLEVEL with double %%, like this: %%ERRORLEVEL%%. Otherwise, it considers it to be TeamCity build parameter. – Yan Sklyarenko Sep 27 '13 at 7:09
  • 2
    What does the ^& do? ss64 says escapes but it seems to me it shouldn't be escaped? – mlhDev May 10 '17 at 13:40
18

Running it from Jenkins needs both ( ) and /B. If you want to ignore the error level 1,2,3,4:

(robocopy XXX YYY) ^& IF %ERRORLEVEL% LEQ 4 exit /B 0
  • 1
    LSS 8 might be even better :) – Ivan Jul 16 '17 at 16:51
13

From this page you can add a section to your batch file that uses the list of error codes to output the errors and run different sections of code:

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

I use this:

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

Some posters above have missed the subtlety of the bit mask. In particular paradroid has missed that errorlevel 3 indicates a completely successful copy.

Note that bit 0x01 if set indicates that some files have been copied even if there were other failures. So any odd numbered errorlevels always indicate that at least some files have been copied. Note also that bit 0x02 simply indicates that there are files at the destination that are not present at the source. This will happen if the /E switch is used and files have been deleted from the source since a previous copy was taken. It should not happen if the /MIR switch is used because that should delete files at the destination to mirror the source (but I haven't tested this).

So both errorlevel 1 AND 3 indicate successful copying of files with no errors. Also errorlevels 0 AND 2 indicate that the destination is up to date and no files were copied.

For what its worth I came up with the following for my simple backup:

if errorlevel 16 echo Backup failed - see reason above & goto done

if errorlevel 8 echo All is not well - backup incomplete & goto done

if errorlevel 4 echo All is not well - some files were mismatched & goto done

if errorlevel 3 echo Backup completed successfully & goto done

if errorlevel 2 echo Backup already up to date - no files copied & goto done

if errorlevel 1 echo Backup completed successfully & goto done

if errorlevel 0 echo Backup already up to date - no files copied & goto done

I chose not to bother about the 'extra' files.

I have no idea what the 'mismatched' error is because it hasn't happened yet but I allowed for it just in case.

6

I agree with Guest John - you really only want to indicate an error if the result is actually 8 or higher.

so to map a robocopy result to a 0 (success) or 1 (fail) result, suitable for use in a SQL Agent job, I am using this:

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

For TeamCity I'm using this and it's working quite well. Thanks to input from MikeWyatt, DaoCacao, and Yan Sklyarenko. I just needed to see a full working example to help visualize the answer.

(robocopy  .\Artifacts\Fitnesse %FitDestinationFolder% /MIR)
IF %%ERRORLEVEL%% LEQ 3 set errorlevel=0
IF %%ERRORLEVEL%% NEQ 0 EXIT /b %%ERRORLEVEL%%
EXIT 0
  • 1
    I'm using a similar robocopy script in my POST-BUILD event .. so dependent libraries are copied over into the consuming .exe application project - which are only referenced via inversion-of-control / service locator pattern. – bkwdesign Feb 12 '15 at 18:54
1

add cmd /c before it for gitlab ci.

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

otherwise EXIT 0 closes the CI pipeline at that point.

0

An example here on how to copy finished files from Visual Studio 2010+ to another folder as Visual Studio expects a 0 not 1 on a good copy.

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

protected by Community Mar 4 '18 at 7:24

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.