152

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?

12 Answers12

146

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
Richard Dingwall
  • 151
  • 2
  • 3
  • 9
52

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

Error    Meaning if set

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

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

2 Some Extra files or directories were detected. No files were copied Examine the output log for details.

4 Some Mismatched files or directories were detected. Examine the output log. Housekeeping might be required.

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

16 Serious error. Robocopy did not copy any files. Either a usage error or an error due to insufficient access privileges on the source or destination directories.

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.

Daniel Beck
  • 111,893
21

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
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
x29a
  • 883
  • 8
  • 11
Mokubai
  • 95,412
9

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.

Richard
  • 6,420
GuestJohn
  • 91
  • 1
  • 1
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
paradroid
  • 23,297
7

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
Nick.Mc
  • 195
2

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.

Scobber
  • 61
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
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 
0

I wasn't able to reliably get the versions with %ERRORLEVEL% to be treated as a failure, so this is what I came up with:

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

All failures get mapped to an error code of 1, otherwise success has code 0.

Note that IF ERRORLEVEL # means "error level ≥ #", hence IF NOT ERRORLEVEL 8 means "error level is less than 8".

Robocopy's return codes only indicate error if they are 8 or more.

Any value greater than 8 indicates that there was at least one failure during the copy operation.

Mark Sowul
  • 3,088
0

Here's how I would do it:

robocopy [...] & if not errorlevel 4 ver > nul

Assuming that extra files are OK, but mismatched files are not, then exit codes 0, 1, 2 and 3 indicate success and all other indicate failure.

(Mismatched meaning we are trying to copy a file, but we can't because there's already a directory with the same name there.)

In batch files/cmd, exit codes set the ERRORLEVEL. To reset the ERRORLEVEL to 0 (success) we can use the fact that ver returns 0 (and discard the output). If it's 4 or greater, we can just leave the ERRORLEVEL unchanged.

Example:

robocopy C:\temp\foo C:\temp\bar test.txt & if not errorlevel 4 ver > nul && echo Copy OK
johv
  • 151