Obtenir que ROBOCOPY renvoie un code de sortie «correct»?


121

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?


2
Il convient également de noter que les 8 premiers codes de sortie (0-7) ne sont apparemment pas des états d'erreur: stackoverflow.com/questions/16533843/psake-and-robocopy-failing
longda le

Réponses:


47

Comme 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 des instructions if / else indiquant que EXIT /B 0lorsque la valeur de retour est 1 ou peut-être 0, et EXIT /B 1sinon. 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.


108

TechNet suggère à ce one-liner de 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.-à-d. 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

8
Agréable. A besoin de crochets autour de la commande robocopy, mais m'a sauvé en utilisant un script wrapper.
TheCodeKing

Je ne pouvais pas faire fonctionner ce one-line comme une étape de construction en ligne de commande dans TeamCity. Je devais le déplacer sur une ligne séparée. J'ai également ajouté l'argument / B à la commande exit, bien que je ne pense pas que cela était nécessaire.
MikeWyatt

Pour le déploiement de Teamcity (et pas seulement de Teamcity), il est utile de taper: IF %ERRORLEVEL% LEQ 3 set errorlevel=0et sur la ligne suivante: if %errorlevel% neq 0 exit /b %errorlevel%(si le fichier de commandes comprend plusieurs opérations, pas seulement robocopy), car les codes OK sont inférieurs à 3. ss64.com/nt/robocopy -exit.html
DaoCacao

6
Dans TeamCity, vous devez vous échapper ERRORLEVELavec le double %%, comme ceci: %% ERRORLEVEL %%. Sinon, il considère qu'il s'agit du paramètre de génération TeamCity.
Yan Sklyarenko

2
Qu'est-ce que le ^&fait? ss64 dit s'échappe mais il me semble qu'il ne faut pas s'échapper?
mlhDev

19

Le lancer depuis Jenkins a besoin des deux ( )et /B. Si vous voulez ignorer le niveau d'erreur 1,2,3,4:

(robocopy XXX YYY) ^& IF %ERRORLEVEL% LEQ 4 exit /B 0

2
LSS 8 pourrait être encore mieux :)
Ivan

13

À partir de 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

8

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

8

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 et ont été effectués

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é et terminé

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'a pas encore eu lieu, mais je l'ai autorisée au cas où.


6

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

2

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

1
J'utilise un script robocopy similaire dans mon événement POST-BUILD. Les bibliothèques dépendantes sont donc copiées dans le projet d'application .exe consommateur - qui n'est référencé que via un modèle de localisateur de service / inversion de contrôle.
bkwdesign

1

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.


0

Un exemple ici sur la façon de copier des fichiers finis à partir de Visual Studio 2010+ dans un autre dossier, car Visual Studio s'attend à ce que 0 soit 1 sur une copie correcte.

cmd /c (robocopy $(TargetDir) X:\$(TargetName) $(TargetFileName) $(TargetFileName).config *.dll *.json *.xml /xx) ^& IF %ERRORLEVEL% LEQ 1 exit 0 
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.