ROBOCOPY dazu bringen, einen "richtigen" Exit-Code zurückzugeben?

121

Ist es möglich, ROBOCOPY mit einem Beendigungscode zum Beenden aufzufordern, der Erfolg oder Misserfolg anzeigt?

Ich verwende ROBOCOPY als Teil meiner TeamCity-Build-Konfigurationen, und es erscheint mir dumm, einen Schritt hinzuzufügen, um den Exit-Code von ROBOCOPY zum Schweigen zu bringen.

Grundsätzlich habe ich folgendes hinzugefügt:

EXIT /B 0

zu dem Skript, das ausgeführt wird.

Dies maskiert jedoch natürlich alle echten Probleme, die ROBOCOPY zurückbringen würde.

Grundsätzlich möchte ich Exit-Codes von 0 für SUCCESS und von ungleich Null für FAILURE anstelle der Bitmaske haben, die ROBOCOPY jetzt zurückgibt.

Oder, wenn ich das nicht haben kann, gibt es eine einfache Folge von Stapelbefehlen, die die Bitmaske von ROBOCOPY in einen ähnlichen Wert übersetzen würden?

Lasse Vågsæther Karlsen
quelle
2
Es sollte auch beachtet werden, dass die ersten 8 Exit-Codes (0-7) anscheinend keine Fehlerzustände sind: stackoverflow.com/questions/16533843/psake-and-robocopy-failing
longda

Antworten:

47

Wie hier hat Robocopy die folgenden Exit-Code-Bits, die den Exit-Code bilden:

0 × 10 Schwerer Fehler. Robocopy hat keine Dateien kopiert. Dies ist entweder ein Verwendungsfehler oder ein Fehler aufgrund unzureichender Zugriffsrechte auf die Quell- oder Zielverzeichnisse.

0 × 08 Einige Dateien oder Verzeichnisse konnten nicht kopiert werden (Kopierfehler sind aufgetreten und das Wiederholungslimit wurde überschritten). Überprüfen Sie diese Fehler weiter.

0 × 04 Einige nicht übereinstimmende Dateien oder Verzeichnisse wurden erkannt. Untersuchen Sie das Ausgabeprotokoll. Housekeeping ist wahrscheinlich notwendig.

0 × 02 Einige zusätzliche Dateien oder Verzeichnisse wurden erkannt. Untersuchen Sie das Ausgabeprotokoll. Möglicherweise ist ein Reinigungsservice erforderlich.

0 × 01 Eine oder mehrere Dateien wurden erfolgreich kopiert (das heißt, neue Dateien sind eingetroffen).

0 × 00 Es sind keine Fehler aufgetreten und es wurde nicht kopiert. Die Quell- und Zielverzeichnisbäume sind vollständig synchronisiert.

Fügen Sie einfach if / else-Anweisungen hinzu, EXIT /B 0die besagen, dass der Rückgabewert 1 oder möglicherweise 0 ist, und EXIT /B 1ansonsten. Auch wenn Dateien möglicherweise kopiert wurden, ist ein Fehler aufgetreten, der manuell behoben werden muss.

Daniel Beck
quelle
108

TechNet schlägt diesen Einzeiler vor, um den Exit-Code in einen traditionelleren Exit-Code umzuwandeln:

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

Oder dies, um den Exit-Code vollständig zu ignorieren (dh es ist egal, ob er fehlgeschlagen ist oder erfolgreich war):

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

Beide obigen Befehle beenden jedoch ein Skript, nachdem die Robokopie ausgeführt wurde. Dies ist insbesondere für CI-Builds ein Problem. Wenn Sie in diesem Szenario Robocopy verwenden möchten, müssen Sie den Fehlercode für irrelevante Beendigungscodes manuell festlegen. Im Folgenden werden alle Fehlercodes unter 8 so umgeschrieben, dass überhaupt kein Fehler auftritt, und das Skript wird fortgesetzt, wenn dies möglich ist.

(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LSS 8 SET ERRORLEVEL = 0
Richard Dingwall
quelle
8
Nett. Benötigt Klammern um den Befehl robocopy, hat mich jedoch mit einem Wrapper-Skript gerettet.
TheCodeKing
Ich konnte diesen Einzeiler nicht als Befehlszeilen-Buildschritt in TeamCity verwenden. Ich musste es in eine separate Zeile verschieben. Ich habe auch das Argument / B zum Befehl exit hinzugefügt, obwohl ich glaube, dass dies nicht erforderlich ist.
MikeWyatt
Für die Teamcity-Bereitstellung (und nicht nur für Teamcity) sollten Sie Folgendes eingeben : IF %ERRORLEVEL% LEQ 3 set errorlevel=0und in der nächsten Zeile: if %errorlevel% neq 0 exit /b %errorlevel%(wenn die Batchdatei aus mehreren Vorgängen besteht, nicht nur aus Robocopy), da die OK-Codes kleiner als 3. ss64.com/nt/robocopy sind -exit.html
DaoCacao
6
In TeamCity sollten Sie das ERRORLEVELmit dem Doppelten %% wie folgt umgehen: %% ERRORLEVEL %%. Andernfalls wird es als TeamCity-Buildparameter betrachtet.
Yan Sklyarenko
2
Was macht der ^&? ss64 sagt Flucht, aber es scheint mir, es sollte nicht entkommen werden?
mlhDev
19

Um es von Jenkins aus zu starten, sind sowohl ( )als auch erforderlich /B. Wenn Sie die Fehlerstufe 1,2,3,4 ignorieren wollen:

(robocopy XXX YYY) ^& IF %ERRORLEVEL% LEQ 4 exit /B 0
Filippo Vitale
quelle
2
LSS 8 könnte noch besser sein :)
Ivan
13

Auf dieser Seite können Sie Ihrer Batchdatei einen Abschnitt hinzufügen, in dem anhand der Liste der Fehlercodes die Fehler ausgegeben und verschiedene Codeabschnitte ausgeführt werden:

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
Mokubai
quelle
8

Ich benutze das:

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
quelle
8

Einige der oben genannten Poster haben die Feinheit der Bitmaske übersehen. Insbesondere hat paradroid übersehen, dass Errorlevel 3 eine vollständig erfolgreiche Kopie anzeigt.

Beachten Sie, dass das gesetzte Bit 0x01 anzeigt, dass einige Dateien kopiert wurden, auch wenn andere Fehler aufgetreten sind. Daher weisen ungerade nummerierte Fehlerebenen immer darauf hin, dass mindestens einige Dateien kopiert wurden. Beachten Sie auch, dass das Bit 0x02 lediglich angibt, dass sich am Zielort Dateien befinden, die an der Quelle nicht vorhanden sind. Dies ist der Fall, wenn die Option / E verwendet wird und Dateien aus der Quelle gelöscht wurden, seit eine vorherige Kopie erstellt wurde. Es sollte nicht passieren, wenn der Schalter / MIR verwendet wird, da dies Dateien am Ziel löschen sollte, um die Quelle zu spiegeln (aber ich habe dies nicht getestet).

So zeigen sowohl Fehlerebene 1 als auch 3 das erfolgreiche Kopieren von Dateien ohne Fehler an. Auch die Fehlerstufen 0 UND 2 zeigen an, dass das Ziel auf dem neuesten Stand ist und keine Dateien kopiert wurden.

Wofür es sich lohnt, habe ich mir für mein einfaches Backup folgendes ausgedacht:

Wenn Fehlerlevel 16 Echo Backup fehlgeschlagen ist - siehe Grund oben & fertig

Wenn Fehlerstufe 8 echo, ist nicht alles in Ordnung - Sicherung unvollständig und fertig

Wenn Fehlerstufe 4 echo, ist nicht alles in Ordnung - einige Dateien stimmen nicht überein und wurden nicht richtig bearbeitet

Wenn Fehlerstufe 3, Echo-Backup erfolgreich abgeschlossen und fertig

wenn errorlevel 2 echo Backup bereits aktuell ist - keine Dateien kopiert & fertig

Wenn Fehlerstufe 1, Echo-Backup erfolgreich abgeschlossen und fertig

wenn errorlevel 0 echo Backup bereits aktuell ist - keine Dateien kopiert & fertig

Ich habe beschlossen, mich nicht um die "zusätzlichen" Dateien zu kümmern.

Ich habe keine Ahnung, was der "nicht übereinstimmende" Fehler ist, weil er noch nicht aufgetreten ist, aber ich habe es für alle Fälle zugelassen.

GuestJohn
quelle
6

Ich stimme Gast John zu - Sie möchten wirklich nur dann einen Fehler anzeigen, wenn das Ergebnis tatsächlich 8 oder höher ist.

Um ein Robocopy-Ergebnis einem 0-Ergebnis (Erfolg) oder 1-Ergebnis (Fehlschlag) zuzuordnen, das für die Verwendung in einem SQL Agent-Job geeignet ist, verwende ich Folgendes:

  IF %ERRORLEVEL% LSS 8 EXIT /B 0
  EXIT /B 1
ElectricLlama
quelle
2

Für TeamCity verwende ich das und es funktioniert ganz gut. Vielen Dank an MikeWyatt, DaoCacao und Yan Sklyarenko. Ich brauchte nur ein voll funktionsfähiges Beispiel, um die Antwort zu visualisieren.

(robocopy  .\Artifacts\Fitnesse %FitDestinationFolder% /MIR)
IF %%ERRORLEVEL%% LEQ 3 set errorlevel=0
IF %%ERRORLEVEL%% NEQ 0 EXIT /b %%ERRORLEVEL%%
EXIT 0
Paul Oliver
quelle
1
Ich verwende ein ähnliches Robocopy-Skript in meinem POST-BUILD-Ereignis. Daher werden abhängige Bibliotheken in das ausführende EXE-Anwendungsprojekt kopiert, auf die nur über das Inversion-of-Control- / Service-Locator-Muster verwiesen wird.
bkwdesign
1

füge cmd / c davor für gitlab ci hinzu.

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

Andernfalls schließt EXIT 0 die CI-Pipeline an diesem Punkt.

Scott Pepper
quelle
0

Ein Beispiel zum Kopieren fertiger Dateien aus Visual Studio 2010+ in einen anderen Ordner, da Visual Studio eine 0 und keine 1 für eine gute Kopie erwartet.

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