Obtendo o ROBOCOPY para retornar um código de saída “correto”?

111

É possível pedir ao ROBOCOPY para sair com um código de saída que indica sucesso ou falha?

Estou usando ROBOCOPY como parte de minhas configurações de compilação do TeamCity, e ter que adicionar uma etapa para apenas silenciar o código de saída do ROBOCOPY parece bobo para mim.

Basicamente, eu adicionei isto:

EXIT /B 0

para o script que está sendo executado.

No entanto, isso, é claro, mascara quaisquer problemas reais que o ROBOCOPY retornaria.

Basicamente, eu gostaria de ter códigos de saída de 0 para SUCESSO e diferente de zero para FALHA em vez da máscara de bits que o ROBOCOPY retorna agora.

Ou, se eu não posso ter isso, há uma sequência simples de comandos em lote que traduzem a máscara de bits de ROBOCOPY para um valor semelhante?

    
por Lasse Vågsæther Karlsen 07.05.2011 / 15:03

10 respostas

43

De acordo com aqui , o Robocopy tem os seguintes bits de código de saída que compõem o código de saída:

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.

Apenas adicione instruções if / else que EXIT /B 0 quando o valor de retorno for 1 ou talvez 0 e EXIT /B 1 caso contrário. Mesmo que os arquivos possam ter sido copiados, há algo errado que precisaria de intervenção manual.

    
por 07.05.2011 / 15:34
93

A TechNet sugere que essa frase única converta o código de saída em um código de saída mais tradicional:

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

Ou para ignorar completamente o código de saída (ou seja, não importa se falhou ou foi bem-sucedido):

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

No entanto, ambos os comandos acima terminarão um script após a execução do robocopy. Esse é um problema especialmente para construções de CI. Se você quiser usar o robocopy nesse cenário, precisará definir o código de erro manualmente para códigos de saída irrelevantes. Abaixo, todos os códigos de erro abaixo de 8 serão reescritos para nenhum erro, e o script será continuado, se possível.

(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LSS 8 SET ERRORLEVEL = 0
    
por 12.01.2018 / 13:58
17

A execução do Jenkins precisa de ( ) e /B . Se você quiser ignorar o nível de erro 1,2,3,4:

(robocopy XXX YYY) ^& IF %ERRORLEVEL% LEQ 4 exit /B 0
    
por 18.06.2012 / 07:26
13

De esta página você pode adicionar uma seção ao seu arquivo de lote que usa a lista de códigos de erro para a saída os erros e executar diferentes seções de código:

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
    
por 07.05.2011 / 15:35
8

Eu uso isso:

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
    
por 07.05.2011 / 16:54
8

Alguns pôsteres acima perderam a sutileza da máscara de bits. Em particular, o paradroid perdeu o nível de erro 3 e indica uma cópia completamente bem sucedida.

Observe que o bit 0x01, se definido, indica que alguns arquivos foram copiados, mesmo se houver outras falhas. Portanto, qualquer erro de número ímpar indica sempre que pelo menos alguns arquivos foram copiados. Observe também que o bit 0x02 simplesmente indica que há arquivos no destino que não estão presentes na origem. Isso acontecerá se a opção / E for usada e os arquivos tiverem sido excluídos da fonte desde que uma cópia anterior foi obtida. Isso não deve acontecer se a opção / MIR for usada porque isso deve excluir arquivos no destino para espelhar a fonte (mas eu não testei isso).

Portanto, ambos os níveis de erro 1 e 3 indicam cópias bem-sucedidas de arquivos sem erros. Também os níveis de erro 0 e 2 indicam que o destino está atualizado e que nenhum arquivo foi copiado.

Para o que vale a pena, desenvolvi o seguinte para o meu backup simples:

se errorlevel 16 echo Backup falhou - veja o motivo acima & goto feito

se errorlevel 8 echo All não está bem - backup incompleto & goto feito

se errorlevel 4 echo Tudo não está bem - alguns arquivos não foram compatíveis & goto feito

se errorlevel 3 echo Backup foi concluído com êxito & goto feito

se errorlevel 2 echo Backup já está atualizado - nenhum arquivo copiado & goto feito

se errorlevel 1 echo Backup foi concluído com êxito & goto feito

se errorlevel 0 ecoar Backup já atualizado - nenhum arquivo copiado & goto feito

Eu escolhi não me preocupar com os arquivos 'extras'.

Eu não tenho ideia do que é o erro "incompatível" porque ainda não aconteceu, mas permiti que fosse apenas por precaução.

    
por 04.04.2014 / 01:56
6

Concordo com o visitante John - você realmente deseja apenas indicar um erro se o resultado for realmente 8 ou superior.

para mapear um resultado de robocopy para um resultado 0 (com êxito) ou 1 (com falha), adequado para uso em um trabalho do SQL Agent, estou usando o seguinte:

  IF %ERRORLEVEL% LSS 8 EXIT /B 0
  EXIT /B 1
    
por 24.10.2014 / 05:36
2

Para o TeamCity, estou usando isso e está funcionando muito bem. Graças à contribuição de MikeWyatt, DaoCacao e Yan Sklyarenko. Eu só precisava ver um exemplo completo de trabalho para ajudar a visualizar a resposta.

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

Um exemplo aqui sobre como copiar arquivos concluídos do Visual Studio 2010+ para outra pasta, já que o Visual Studio espera um 0 diferente de 1 em uma boa cópia.

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

adicione o cmd / c antes dele para o gitlab ci.

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

caso contrário, o EXIT 0 fecha o pipeline da CI nesse ponto.

    
por 08.11.2017 / 23:20