michelo82
Goto Top

For Schleife - Robocopy gibt trotz Setlocal EnableDelayedExpansion nur Errorlevel 0 zurück

Hallo,

und zwar bastel ich an einem Sicherungsskript welches mit Robocopy die Daten kopiert, die Zeit dieses Vorganges misst, das ganze in eine HTML Datei speichert und mir per Mail sendet. Hier würde ich gern das Errorlevel von Robocopy ausgeben. Leider bekomme ich nur Errorlevel 0 zurück. Ich habe wohl einen Fehler in meiner Syntax.

Hier einmal das ganze Skript (etwas eingekürzt):
::--------------------------------------------------------
::-- Taegliche_Sicherung
::-- Letzte Änderung: 20.06.2014
::-- Author: michelo82
::--------------------------------------------------------
@echo off
::--------------------------------------------------------
::-- Variablen
::-- Pfad zur HTML Datei
set html="D:\robocopy_log.html"  

::-- prüfe ob HTML Datei vorhanden, wenn ja diese löschen
if exist %html% del %html% /q

::-- Robocopy starten
echo Robocopy arbeitet
call::RoboCopyFunktion "robocopy "e:\test1" "d:\test1" /MIR /TEE" 
::call::RoboCopyFunktion "u.s.w"  

::-- schicke Bestätigungsmail
call:SendMailFunkion

::--------------------------------------------------------
::-- Funktions sektion beginnt hier
::--------------------------------------------------------

:RoboCopyFunktion
::-- starte Timer - dauer der Batch ermitteln
set /a timerstart=((1%time:~0,2%-100)*60*60)+((1%time:~3,2%-100)*60)+(1%time:~6,2%-100)

::-- Robocopy starten und Zeit aus Robocopy Ausgabe ermitteln
for /f "tokens=*" %%g in ('%~1^|findstr "Quelle"') do set Quelle=%%g  
for /f "tokens=*" %%g in ('%~1^|findstr "Gestartet"') do set Gestartet=%%g  
for /f "tokens=*" %%g in ('%~1^|findstr "Beendet"') do set Beendet=%%g  
call:ErrorLevelFunktion

::-- beende Timer - dauer der Batch ermitteln
set /a timerstop=((1%time:~0,2%-100)*60*60)+((1%time:~3,2%-100)*60)+(1%time:~6,2%-100)
set /a timeseks=(%timerstop%-%timerstart%)
set /a timemins=(%timerstop%-%timerstart%)/60
echo Dauer Sicherung %Quelle%: %timemins% min. %timeseks% sek.

::-- baue Ausgabe für Bestätigungsmail und hänge diese in eine HTML-Datei an
echo ^<html^>^<body^>^<h3^>%Quelle%^</h3^>^<table border="1"^>^<tr^>^<td^>^<b^>Errorlevel^</b^>^</td^>^<td^>%bodytext%^</td^>^</tr^>^<tr^>^<td^>^<b^>Gestartet^</b^>^</td^>^<td^>%Gestartet%^</td^>^</tr^>^<tr^>^<td^>^<b^>Beendet^</b^>^</td^>^<td^>%Beendet%^</td^>^</tr^>^<tr^>^<td^>^<b^>Dauer des Vorgangs^</b^>^</td^>^<td^>%timemins% min. %timeseks% sek.^</td^>^</tr^>^</table^>^</body^>^</html^> >> %html%  
goto:eof

::-- Errorlevel bestimmen
:ErrorLevelFunktion
if /i %ErrorLevel%==0 (
set bodytext=Es wurden keine Dateien kopiert. Keine Fehler. Keine Dateien stimmen nicht ueberein. Die Dateien sind bereits im Zielverzeichnis vorhanden; aus diesem Grund wurde beim Kopieren uebersprungen.
)
if /i %ErrorLevel%==1 (
set bodytext=Alle Dateien wurden erfolgreich kopiert.
)
if /i %ErrorLevel%==2 (
set bodytext=Es gibt einige zusaetzlichen Dateien im Zielverzeichnis, die nicht im Quellverzeichnis vorhanden sind. Es wurden keine Dateien kopiert.
)
if /i %ErrorLevel%==3 (
set bodytext=Einige Dateien wurden kopiert. Zusaetzliche Dateien waren vorhanden. Keine Fehler.
)
if /i %ErrorLevel%==5 (
set bodytext=Einige Dateien wurden kopiert. Einige Dateien stimmten nicht ueberein. Keine Fehler.
)
if /i %ErrorLevel%==6 (
set bodytext=Zusaetzliche Dateien und nicht uebereinstimmenden Dateien vorhanden sind. Es wurden keine Dateien kopiert, und es sind keine Fehler aufgetreten. Dies bedeutet, dass die Dateien im Zielverzeichnis bereits vorhanden sind.
)
if /i %ErrorLevel%==7 (
set bodytext=Dateien kopiert wurden, ein Dateikonflikt vorhanden war, und zusaetzliche Dateien vorhanden waren.
)
if /i %ErrorLevel%==8 (
set bodytext=Mehrere Dateien wurden nicht kopiert.
)
if %ErrorLevel% GTR 8 (
set bodytext=groesser als 8 - unbedingt manuell pruefen.
)
goto:eof

::-- Bestätigungsmail senden
:SendMailFunkion
sendmail.exe to:mailadresse subject:"Sicherung" smtp:mailserver from:mailadresse html bodytext:"Bitte Anhang pruefen..." add:%html%  
goto:eof

So nun hätte ich meine RobocopyFunktion wie folgt umgebaut um das Errorlevel auszugeben:
...
@echo off & Setlocal EnableDelayedExpansion
...
...
...

:RoboCopyFunktion
::-- starte Timer - dauer der Batch ermitteln
set /a timerstart=((1%time:~0,2%-100)*60*60)+((1%time:~3,2%-100)*60)+(1%time:~6,2%-100)

::-- Robocopy starten und Zeit aus Robocopy Ausgabe ermitteln
for /f "tokens=*" %%g in ('%~1^|findstr "Quelle"') do set Quelle=%%g  
for /f "tokens=*" %%g in ('%~1^|findstr "Gestartet"') do set Gestartet=%%g  
for /f "tokens=*" %%g in ('%~1^|findstr "Beendet"') do set Beendet=%%g do (  
set Beendet=%%g
echo !ERRORLEVEL!
)

Leider bekomme ich hier immer 0 als Rückgabewert. Was mache ich falsch?

Hat jemand einen Tipp für mich? Vielen Dank schonmal.

Content-Key: 241802

Url: https://administrator.de/contentid/241802

Printed on: April 25, 2024 at 23:04 o'clock

Member: Snowman25
Snowman25 Jun 25, 2014 at 09:52:06 (UTC)
Goto Top
Hallo @michelo82,

der Errorlevel ist vom FINDSTR-Command gesetzt.

Gruß,
@Snowman25
Member: michelo82
michelo82 Jun 25, 2014 at 12:22:22 (UTC)
Goto Top
Danke für deine Antwort.
Wie komme ich dann an das Robocopy errorlevel? Das Findstr brauche ich für meine Ausgabe.
Member: Snowman25
Snowman25 Jun 25, 2014 updated at 15:08:03 (UTC)
Goto Top
Warum machst du's nicht auf dem "normalen" Weg, dass du das LOG von robocopy speicherst und verarbeitest?
Wenn du es mit START /WAIT ausführst kannst du sichergehen, dass der Vorgang abgeschlossen ist, bevor weitere Aktionen durchlaufen.
Denn DAS: for /f "tokens=*" %%g in ('%~1^|findstr "Quelle"') do set Quelle=%%g ist schon eine SEHR Eigensinnige Variante.

Du startest dabei übrigens 3 mal den gleichen Vorgang. Wieso?
Schick dir doch einfach das Robocopy-Log anstelle der HTML-Bastelei?
Member: Friemler
Friemler Jun 25, 2014 at 18:31:20 (UTC)
Goto Top
Hallo michelo82,

so weit ich weiß, liefert Robocopy nur in der alten Version XP010 einen aussagekräftigen Errorlevel zurück. Die neueren Versionen (XP026 und die in den Betriebssystemen ab Vista enthaltenen) liefern immer 0 als Errorlevel.

Du kannst das ja sehr einfach testen, indem Du einen RoboCopy-Befehl absetzt, der auf jeden Fall fehl schlagen muss (z.B. nicht existierender Quell- oder Zielpfad).

Gruß
Friemler
Member: michelo82
michelo82 Jun 26, 2014 at 09:16:31 (UTC)
Goto Top
Hallo,

@Friemler: Robocopy liefert schon errorlevel zurück. Das passt schon...
@Snowman25: Ich denke du hast recht, ich muss das nochmal anpassen und mir meine Ausgabe aus den Logs basteln.

Ich wollte eben mit dieser Methode eine ganz schlanke Ausgabe erreichen. Quasi Tabellarisch Servername, Gestartet, Beendet und die Gesamtdauer in Minuten.