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


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

Eu estou usando o ROBOCOPY como parte das 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 obviamente 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, existe uma sequência simples de comandos em lote que traduziria a máscara de bits de ROBOCOPY para um valor semelhante?


110


origem


Também deve ser notado que os primeiros 8 códigos de saída (0-7) aparentemente não são estados de erro: stackoverflow.com/questions/16533843/psake-and-robocopy-failing - longda


Respostas:


Conforme Aqui, Robocopy tem os seguintes bits de código de saída que compõem o código de saída:

0 × 10 Erro grave. O Robocopy não copiou nenhum arquivo. Isso é um erro de uso ou um erro devido a privilégios de acesso insuficientes nos diretórios de origem ou de destino.

0 × 08 Alguns arquivos ou diretórios não puderam ser copiados (ocorreram erros de cópia e o limite de tentativas foi excedido). Verifique esses erros ainda mais.

0 × 04 Alguns arquivos ou diretórios incompatíveis foram detectados. Examine o log de saída. O serviço de limpeza é provavelmente necessário.

0 × 02 Alguns arquivos ou diretórios extras foram detectados. Examine o log de saída. Algumas tarefas domésticas podem ser necessárias.

0 × 01 Um ou mais arquivos foram copiados com sucesso (isto é, novos arquivos chegaram).

0 × 00 Nenhum erro ocorreu e nenhuma cópia foi feita. As árvores de diretório de origem e destino são completamente sincronizadas.

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


43





TechNet sugere este one-liner para converter 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 isso para ignorar completamente o código de saída (ou seja, não importa se ele 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

92



Agradável. Precisa de colchetes ao redor do comando robocopy, mas me salvou usando um script de wrapper. - TheCodeKing
Eu não consegui fazer esse one-liner funcionar como uma etapa de compilação da Command Line no TeamCity. Eu tive que movê-lo para uma linha separada. Eu também adicionei o argumento / B ao comando de saída, embora eu não ache que isso seja necessário. - MikeWyatt
Para a implantação do Teamcity (e não apenas o Teamcity), é útil digitar: IF %ERRORLEVEL% LEQ 3 set errorlevel=0 e na próxima linha: if %errorlevel% neq 0 exit /b %errorlevel% (se o arquivo de lote consistir em várias operações, não apenas em robocopy), porque os códigos OK são menores que 3. ss64.com/nt/robocopy-exit.html - DaoCacao
No TeamCity, você deve escapar do ERRORLEVEL com double %%, assim: %% ERRORLEVEL %%. Caso contrário, considera que seja o parâmetro de construção do TeamCity. - Yan Sklyarenko
O que faz o ^& Faz? ss64 diz fugas mas parece-me que não deveria ser escapado? - mlhDev


Executá-lo de Jenkins precisa de ambos ( ) 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

17



LSS 8 pode ser ainda melhor :) - Ivan


A partir 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 gerar 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

13





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

8





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

Observe que o bit 0x01, se configurado, 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 eu vim com o seguinte para o meu backup simples:

if errorlevel 16 echo Backup falhou - veja o motivo acima & goto done

if errorlevel 8 echo Tudo não está bem - backup incompleto & goto done

if errorlevel 4 echo Tudo não está bem - alguns arquivos foram incompatíveis e goto done

if errorlevel 3 echo Backup concluído com sucesso e concluído

if errorlevel 2 echo Backup já atualizado - nenhum arquivo copiado e goto feito

if errorlevel 1 echo Backup concluído com êxito e concluído

if errorlevel 0 echo Backup já atualizado - nenhum arquivo copiado e goto feito

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

Eu não tenho idéia do que o erro "incompatível" é porque não aconteceu ainda, mas eu permiti para isso apenas no caso.


8





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

Portanto, 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

6