Far ottenere a ROBOCOPY un codice di uscita "corretto"?


121

È possibile chiedere a ROBOCOPY di uscire con un codice di uscita che indica l'esito positivo o negativo?

Sto usando ROBOCOPY come parte delle configurazioni di build di TeamCity, e dover aggiungere un passaggio per mettere a tacere il codice di uscita di ROBOCOPY mi sembra sciocco.

Fondamentalmente, ho aggiunto questo:

EXIT /B 0

allo script che viene eseguito.

Tuttavia, questo ovviamente nasconde tutti i problemi reali che la ROBOCOPIA avrebbe restituito.

Fondamentalmente, vorrei avere i codici di uscita 0 per SUCCESSO e diversi da zero per GUASTO invece della maschera di bit che ROBOCOPY restituisce ora.

Oppure, se non posso averlo, c'è una semplice sequenza di comandi batch che tradurrebbe la maschera di bit di ROBOCOPY in un valore simile?


2
Va inoltre notato che i primi 8 codici di uscita (0-7) sono a quanto pare non errore informa: stackoverflow.com/questions/16533843/psake-and-robocopy-failing
Longda

Risposte:


47

Come qui , Robocopy ha i seguenti bit del codice di uscita che compongono il codice di uscita:

0 × 10 Errore grave. Robocopy non ha copiato alcun file. Questo è un errore di utilizzo o un errore a causa di privilegi di accesso insufficienti nelle directory di origine o di destinazione.

0 × 08 Non è stato possibile copiare alcuni file o directory (si sono verificati errori di copia e il limite di tentativi è stato superato). Controlla ulteriormente questi errori.

0 × 04 Sono stati rilevati alcuni file o directory non corrispondenti. Esaminare il registro di output. Le pulizie sono probabilmente necessarie.

0 × 02 Sono stati rilevati alcuni file o directory extra. Esaminare il registro di output. Alcune pulizie potrebbero essere necessarie.

0 × 01 Uno o più file sono stati copiati correttamente (ovvero sono arrivati ​​nuovi file).

0 × 00 Non si sono verificati errori e non è stata eseguita alcuna copia. Gli alberi delle directory di origine e destinazione sono completamente sincronizzati.

Basta aggiungere le istruzioni if ​​/ else che EXIT /B 0quando il valore restituito è 1 o forse 0 e in caso EXIT /B 1contrario. Anche se i file potrebbero essere stati copiati, c'è qualcosa di sbagliato che avrebbe bisogno di un intervento manuale.


108

TechNet suggerisce questo one-liner per convertire il codice di uscita in un codice di uscita più tradizionale:

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

O questo per ignorare completamente il codice di uscita (ovvero non preoccuparti se fallito o riuscito):

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

Tuttavia, entrambi i comandi precedenti interromperanno uno script dopo l'esecuzione del robocopy. Questo è un problema soprattutto per le build degli elementi della configurazione. Se si desidera utilizzare robocopy in questo scenario, è necessario impostare manualmente il codice di errore per i codici di uscita non pertinenti. Di seguito, tutti i codici di errore inferiori a 8 verranno riscritti senza errori e lo script verrà continuato se possibile.

(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LSS 8 SET ERRORLEVEL = 0

8
Bello. Ha bisogno di parentesi attorno al comando robocopy, ma mi ha salvato usando uno script wrapper.
TheCodeKing

Non sono riuscito a far funzionare questo one-liner come fase di creazione della riga di comando in TeamCity. Ho dovuto spostarlo su una linea separata. Ho anche aggiunto l'argomento / B al comando exit, anche se non credo fosse necessario.
MikeWyatt,

Per la distribuzione di Teamcity (e non solo Teamcity) è utile digitare: IF %ERRORLEVEL% LEQ 3 set errorlevel=0e nella riga successiva: if %errorlevel% neq 0 exit /b %errorlevel%(se il file batch è composto da più operazioni, non solo robocopy), perché i codici OK sono inferiori a 3. ss64.com/nt/robocopy -exit.html
DaoCacao l'

6
In TeamCity, dovresti sfuggire al ERRORLEVELdoppio %%, in questo modo: %% ERRORLEVEL %%. Altrimenti, lo considera un parametro di build di TeamCity.
Yan Sklyarenko,

2
Che cosa ^&fa? ss64 dice escape ma mi sembra che non dovrebbe essere evitato?
mlhDev,

19

Eseguirlo da Jenkins ha bisogno di entrambi ( )e /B. Se si desidera ignorare il livello di errore 1,2,3,4:

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

2
LSS 8 potrebbe essere anche migliore :)
Ivan

13

Da questa pagina è possibile aggiungere una sezione al file batch che utilizza l'elenco dei codici di errore per generare gli errori ed eseguire diverse sezioni di codice:

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

Io uso questo:

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

Alcuni poster sopra hanno perso la sottigliezza della maschera per bit. In particolare paradroid ha mancato che il livello di errore 3 indica una copia completamente riuscita.

Si noti che il bit 0x01 se impostato indica che alcuni file sono stati copiati anche se si sono verificati altri errori. Pertanto, qualsiasi livello di errore con numeri dispari indica sempre che almeno alcuni file sono stati copiati. Si noti inoltre che il bit 0x02 indica semplicemente che ci sono file nella destinazione che non sono presenti nella sorgente. Ciò accadrà se si utilizza l'opzione / E e i file sono stati eliminati dall'origine da quando è stata eseguita una copia precedente. Non dovrebbe accadere se si utilizza l'opzione / MIR perché ciò dovrebbe eliminare i file nella destinazione per rispecchiare l'origine (ma non l'ho provato).

Pertanto, sia il livello di errore 1 che il 3 indicano una copia riuscita dei file senza errori. Anche i livelli di errore 0 E 2 indicano che la destinazione è aggiornata e che nessun file è stato copiato.

Per quello che vale ho pensato a quanto segue per il mio semplice backup:

se errorlevel 16 echo Backup fallito - vedi motivo sopra e vai a fatto

se errorlevel 8 echo Non tutto va bene - backup incompleto e goto fatto

se errorlevel 4 echo Non tutto va bene - alcuni file non sono stati trovati correttamente e sono stati fatti

se errorlevel 3 echo Backup completato correttamente e goto fatto

se errorlevel 2 echo Backup già aggiornato - nessun file copiato e goto fatto

se errorlevel 1 echo Backup completato correttamente e goto fatto

se errorlevel 0 echo Backup già aggiornato - nessun file copiato e goto fatto

Ho scelto di non preoccuparmi dei file "extra".

Non ho idea di quale sia l'errore "non corrispondente" perché non si è ancora verificato, ma l'ho permesso per ogni evenienza.


6

Sono d'accordo con Guest John: vuoi davvero indicare un errore solo se il risultato è in realtà 8 o superiore.

quindi per mappare un risultato robocopy su un risultato 0 (successo) o 1 (esito negativo), adatto per l'uso in un lavoro di Agente SQL, sto usando questo:

  IF %ERRORLEVEL% LSS 8 EXIT /B 0
  EXIT /B 1

2

Per TeamCity lo sto usando e funziona abbastanza bene. Grazie al contributo di MikeWyatt, DaoCacao e Yan Sklyarenko. Avevo solo bisogno di vedere un esempio completo di lavoro per aiutare a visualizzare la risposta.

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

1
Sto usando uno script robocopy simile nel mio evento POST-BUILD .. quindi le librerie dipendenti vengono copiate nel progetto applicativo .exe che fa riferimento solo tramite il modello di localizzazione di inversione di controllo / servizio.
bkwdesign,

1

aggiungi cmd / c prima di esso per gitlab ci.

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

altrimenti EXIT 0 chiude la pipeline CI in quel punto.


0

Un esempio qui su come copiare i file finiti da Visual Studio 2010+ in un'altra cartella poiché Visual Studio prevede uno 0 non 1 su una buona copia.

cmd /c (robocopy $(TargetDir) X:\$(TargetName) $(TargetFileName) $(TargetFileName).config *.dll *.json *.xml /xx) ^& IF %ERRORLEVEL% LEQ 1 exit 0 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.