Est-il possible de demander à ROBOCOPY de sortir avec un code de sortie indiquant le succès ou l'échec?
J'utilise ROBOCOPY dans le cadre de mes configurations de construction TeamCity, et devoir ajouter une étape pour simplement faire taire le code de sortie de ROBOCOPY me semble ridicule.
En gros, j'ai ajouté ceci:
EXIT /B 0
au script en cours d'exécution.
Cependant, cela masque bien entendu tous les problèmes réels que ROBOCOPY renverrait.
En gros, j'aimerais avoir des codes de sortie de 0 pour SUCCESS et non nuls pour FAILURE au lieu du masque binaire renvoyé par ROBOCOPY.
Ou, si je ne peux pas en avoir, existe-t-il une simple séquence de commandes batch permettant de traduire le masque binaire de ROBOCOPY en une valeur similaire?
Selon ici , Robocopy a les bits de code de sortie suivants qui constituent le code de sortie:
0 × 10 Erreur grave. Robocopy n'a copié aucun fichier. Il s'agit d'une erreur d'utilisation ou d'une erreur due à des privilèges d'accès insuffisants sur les répertoires source ou de destination.
0 × 08 Certains fichiers ou répertoires n'ont pas pu être copiés (des erreurs de copie se sont produites et la limite de tentatives a été dépassée). Vérifiez ces erreurs plus loin.
0 × 04 Des fichiers ou des répertoires incompatibles ont été détectés. Examinez le journal de sortie. Le ménage est probablement nécessaire.
0 × 02 Des fichiers ou des répertoires supplémentaires ont été détectés. Examinez le journal de sortie. Un peu de ménage peut être nécessaire.
0 × 01 Un ou plusieurs fichiers ont été copiés avec succès (c'est-à-dire que de nouveaux fichiers sont arrivés).
0 × 00 Aucune erreur ne s'est produite et aucune copie n'a été effectuée. Les arborescences de répertoires source et de destination sont complètement synchronisées.
Ajoutez simplement les instructions if/else qui EXIT /B 0
lorsque la valeur de retour est 1 ou peut-être 0, et EXIT /B 1
sinon. Même si des fichiers ont peut-être été copiés, il y a quelque chose qui ne va pas et qui nécessite une intervention manuelle.
TechNet suggère ce one-liner pour convertir le code de sortie en un code de sortie plus traditionnel:
(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LEQ 1 exit 0
Ou ceci pour ignorer complètement le code de sortie (c'est-à-dire ne vous souciez pas de savoir s'il a échoué ou réussi):
(robocopy c:\dirA c:\dirB *.*) ^& exit 0
Cependant, les deux commandes ci-dessus mettront fin à un script après l'exécution de robocopy. C'est un problème en particulier pour les versions de CI. Si vous souhaitez utiliser robocopy dans ce scénario, vous devez définir le code d'erreur manuellement pour les codes de sortie non pertinents. En dessous, tous les codes d’erreur en dessous de 8 seront réécrits sans erreur du tout et le script sera poursuivi si possible.
(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LSS 8 SET ERRORLEVEL = 0
L'exécuter à partir de Jenkins nécessite à la fois ( )
et /B
. Si vous voulez ignorer le niveau d'erreur 1,2,3,4:
(robocopy XXX YYY) ^& IF %ERRORLEVEL% LEQ 4 exit /B 0
Depuis cette page vous pouvez ajouter une section à votre fichier de commandes qui utilise la liste des codes d'erreur pour générer les erreurs et exécuter différentes sections de 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
J'utilise ceci:
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
Certaines affiches ci-dessus ont manqué la subtilité du masque. En particulier, paradroid a manqué que errorlevel 3 indique une copie complètement réussie.
Notez que le bit 0x01, s'il est défini, indique que certains fichiers ont été copiés, même s'il y a eu d'autres échecs. Ainsi, tous les niveaux d'erreur impairs et numérotés indiquent toujours qu'au moins certains fichiers ont été copiés. Notez également que le bit 0x02 indique simplement qu'il existe des fichiers à la destination qui ne sont pas présents à la source. Cela se produira si le commutateur/E est utilisé et que les fichiers ont été supprimés de la source depuis la copie précédente. Cela ne devrait pas arriver si le commutateur/MIR est utilisé, car cela devrait supprimer les fichiers de la destination pour refléter la source (mais je n'ai pas testé cela).
Ainsi, les deux niveaux d'erreur 1 et 3 indiquent que la copie de fichiers a réussi sans erreur. De plus, les niveaux d'erreur 0 et 2 indiquent que la destination est à jour et qu'aucun fichier n'a été copié.
Pour ce qui en vaut la peine, j’ai proposé ce qui suit pour ma sauvegarde simple:
si errorlevel 16 echo Backup a échoué - voir la raison ci-dessus & goto terminé
si errorlevel 8 echo Tout ne va pas bien - sauvegarde incomplète & goto fait
si errorlevel 4 echo Tout ne va pas bien - certains fichiers ont été mal assortis
si errorlevel 3 echo Backup est terminé et terminé
si errorlevel 2 echo Backup est déjà à jour - pas de fichiers copiés et continuez
si errorlevel 1 echo Backup est terminé avec succès et obtenu
si errorlevel 0 echo Backup est déjà à jour - pas de fichiers copiés et continuez
J'ai choisi de ne pas me soucier des fichiers «supplémentaires».
Je ne sais pas du tout quelle est l'erreur "incompatible" car elle n'est pas encore arrivée, mais je l'ai autorisée au cas où.
Je suis d'accord avec Guest John - vous voulez vraiment indiquer une erreur si le résultat est réellement égal à 8 ou plus.
donc pour mapper un résultat robocopy à un résultat 0 (succès) ou 1 (échec), convenant à une utilisation dans un travail d'agent SQL, j'utilise ceci:
IF %ERRORLEVEL% LSS 8 EXIT /B 0
EXIT /B 1
Pour TeamCity, je l’utilise et cela fonctionne assez bien. Merci aux contributions de MikeWyatt, DaoCacao et Yan Sklyarenko. J'avais juste besoin de voir un exemple de travail complet pour aider à visualiser la réponse.
(robocopy .\Artifacts\Fitnesse %FitDestinationFolder% /MIR)
IF %%ERRORLEVEL%% LEQ 3 set errorlevel=0
IF %%ERRORLEVEL%% NEQ 0 EXIT /b %%ERRORLEVEL%%
EXIT 0
ajoutez cmd/c devant lui pour gitlab ci.
cmd /c (robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LEQ 1 exit 0
sinon EXIT 0 ferme le pipeline CI à ce stade.
Un exemple ici sur la façon de copier des fichiers finis à partir de Visual Studio 2010+ dans un autre dossier, car Visual Studio attend un 0 et 1 sur une copie correcte.
cmd /c (robocopy $(TargetDir) X:\$(TargetName) $(TargetFileName) $(TargetFileName).config *.dll *.json *.xml /xx) ^& IF %ERRORLEVEL% LEQ 1 exit 0