nother
Goto Top

Robocopy erstellt im differentiellen Backup-Ordner auch leere Verzeichnisse

Hallo Leute,
brauche mal hier ein wenig Unterstützung zum Thema Robocopy und Batch-Script!
Das Script ist natürlich nicht komplett aus meiner Feder, die Code-Schnipsel sind hier und da zusammengetragen.
Insbesondere bitte ich Biber und Bastla sich das ganze mal näher zu betrachten...
Bin sonst nur stiller Leser und habe eure Namen schon des Öfteren im Zusammenhang mit Batch-Skripten gelesen.
Robocopy nutze ich schon sehr lange, daher kenne ich die Parameter eigentlich ganz gut.

Zwei "Anliegen" habe ich aber dennoch: Dieses Script macht am 01. eines Monats ein Vollbackup und den restlichen Tagen
ein differentielles. Klappt auch soweit super!
Aber: In den differentiellen Ordnern werden immer die komplette Verzeichnisstruktur erstellt, obwohl kein Archiv-Bit gesetzt ist.
Ist zwar nur ein, für mich "Schönheitsfehler", nervt mich aber ungemein. Kann man das nicht irgendwie beseitigen?

Das andere Problem ist die offensichtliche Ahnungslosigkeit wie man "schöne Scripte" schreibt.
Da ich nur rudimentären Plan habe und vieles durch "Try and error" erlernt habe, ist das Script nicht wirklich "sauber".
Z.B. die Sache mit der doppelten Logfile-Zusammenfassung. Hatte Probleme mit dem Errorlevel...
Geht das vielleicht eleganter?
Auch das "Umschalten" am 01. mit den anderen Parametern find ich nicht wirklich schön.
Wenn einer Lust und Zeit hat, kann er ja gern seine Meinung dazu äußern.

Vielen Dank

:: Robocopysicherung Nas01 incl. Mailversandt
:: Zu befüllen sind die Variablen für Robocopy und dessen Logfile
:: sowie optional den Mailer
::--------------------------------------------------------------------------------
::Achtung! Ganz unten werden nur die letzten 5 Versionen behalten-----------------
::ist aber zur Sicherheit auskommentiert -----------------------------------------
::--------------------------------------------------------------------------------
@ECHO OFF & SETLOCAL
::		------------------ Codepage ändern für Umlaute im Log --------------------
chcp 1252
::		------------------ Variablen leeren --------------------------------------
set mydate=
set Quelle=
set Ziel=
set par=
set Logfile=
set befehl=
set mailsrv=
set mailuser=
set mailuserPW=
set mailfrom=
set betreff=
set pathblat=
set mailto=
set body=
::		------------------ eventuell alte vorhandene Dateien löschen -------------
if exist temp.txt del temp.txt
if exist logfile.log del logfile.log
::		------------------ allgemeine Variablen: Datum zerlegen 1 ----------------
for /F "tokens=1-3 delims=/. " %%a in ('date/T') do set mydate=%%c-%%b-%%a  
::		------------------ für Monats-Ordner anlegen: Datum zerlegen 2 -----------
set TT=%date:~0,2%
set MM=%date:~3,2%
set YYYY=%date:~6,4%
::		------------------ Variable Quelle ---------------------------------------
set quelle=\\NAS-IP\Backup
::		------------------ Variable Zielverzeichnis ------------------------------
set backuproot=f:\
::		------------------ lege ein Monatsordner an ------------------------------
set ziel=%BackupRoot%\%MM%\%mydate%
set par=/S /A /MT /NP /NDL /V /FP /XJD /TS /FFT /TEE /R:1 /W:1 /XF desktop.ini Thumbs.db /XD $RECYCLE.BIN 
::		------------------ Logfile für Robocopy ----------------------------------
::		------------------ ACHTUNG: Pfad muss vorhanden sein! --------------------
set log=/LOG:%BackupRoot%Logs\%mydate%.log
::		------------------ Variablen für den Mailer ------------------------------
set logfile=%BackupRoot%Logs\%mydate%.log
set mailsrv=hosteurope.de:587
set mailuser=
set mailuserPW=
set mailfrom=robocopy@firma.de
set pathblat=C:\Programme\blat\
set mailto=admin@firma.de
set body=temp.txt
::		------------------ Attribut am 01. des Monats zurücksetzen ---------------
::		------------------ den Parameter /A durch /M ersetzen --------------------
::		------------------ Vollständige Sicherung und Attrib /A raus -------------
::		------------------ Darauffolgenede Tage werden differentiell gesichert ---
if %TT% == 01 attrib +a "%quelle%\"*.* /s /d & set par=/S /M /MT /NP /NDL /V /FP /XJD /TS /FFT /TEE /R:1 /W:1 /XF desktop.ini Thumbs.db /XD $RECYCLE.BIN  
if %TT% == 01 ping localhost -n 9 >nul
::		------------------ Robocopy ----------------------------------------------
:robo
robocopy.exe %quelle% %ziel% %par% %log%
::		------------------ Errorlevel von Robocopy überprüfen --------------------
if %errorlevel% == 16 set betreff=FATAL ERROR & Goto mail2
if %errorlevel% == 15 set betreff=OKCOPY + FAIL + MISMATCHES + XTRA & Goto mail2
if %errorlevel% == 14 set betreff=FAIL + MISMATCHES + XTRA & Goto mail2
if %errorlevel% == 13 set betreff=OKCOPY + FAIL + MISMATCHES & Goto mail2
if %errorlevel% == 12 set betreff=FAIL + MISMATCHES & Goto mail2
if %errorlevel% == 11 set betreff=OKCOPY + FAIL + XTRA & Goto mail2
if %errorlevel% == 10 set betreff=FAIL + XTRA & Goto mail2
if %errorlevel% == 9  set betreff=OKCOPY + FAIL & Goto mail2
if %errorlevel% == 8  set betreff=FAILED COPIES & Goto mail2
if %errorlevel% == 7  set betreff=OKCOPY + MISMATCHES + XTRA & Goto mail2
if %errorlevel% == 6  set betreff=MISMATCHES + XTRA & Goto mail2
if %errorlevel% == 5  set betreff=OKCOPY + MISMATCHES & Goto mail2
if %errorlevel% == 4  set betreff=MISMATCHES & Goto mail2
if %errorlevel% == 3  set betreff=Copy successful ^& EXTRA Files deleted & Goto mail2
if %errorlevel% == 2  set betreff=EXTRA Files deleted & Goto mail2
if %errorlevel% == 1  set betreff=Copy successful & Goto logausw
if %errorlevel% == 0  set betreff=-- Nothing to do -- & Goto logausw
::		------------------ Bestimmte Zeilen auslesen -----------------------------
:logausw
ping localhost -n 9 >nul
find /i "Gestartet:" %Logfile% >> temp.txt  
find /i "Quelle :" %Logfile% >> temp.txt  
find /i "Ziel :" %Logfile% >> temp.txt  
find /i "Optionen:" %Logfile% >> temp.txt  
echo. >> temp.txt
echo ----------------------------------------------------------------------------- >> temp.txt
find /i "Der Prozess" %Logfile% >> temp.txt  
echo ----------------------------------------------------------------------------- >> temp.txt
find /i "Insgesamt" %Logfile% >> temp.txt  
find /i "Verzeich.:" %Logfile% >> temp.txt  
find /i "Dateien:" %Logfile% >> temp.txt  
find /i "Bytes:" %Logfile% >> temp.txt  
echo ----------------------------------------------------------------------------- >> temp.txt
find /i "Zeiten:" %Logfile%  >> temp.txt  
find /i "Beendet:" %Logfile% >> temp.txt  
type temp.txt | find /i /v "%Logfile%" > temp2.txt  
del temp.txt
ren temp2.txt temp.txt
echo. >> temp.txt
echo. >> temp.txt
ping localhost -n 9 >nul
::		------------------ Bestimmte Zeilen auslesen Ende ------------------------
:mail1
::		------------------ Mailer1 Zusammenfassung versenden ---------------------
%pathblat%\blat.exe %body% -to %mailto% -server %mailsrv% -u %mailuser% -pw %mailuserPW% -debug -timestamp -subject "%betreff%"  
goto clean
::		------------------ Mailer2 für Fehler und Komplettes Logfile--------------
:mail2
ping localhost -n 9 >nul
find /i "Gestartet:" %Logfile% >> temp.txt  
find /i "Quelle :" %Logfile% >> temp.txt  
find /i "Ziel :" %Logfile% >> temp.txt  
find /i "Optionen:" %Logfile% >> temp.txt  
echo. >> temp.txt
echo ----------------------------------------------------------------------------- >> temp.txt
find /i "Der Prozess" %Logfile% >> temp.txt  
echo ----------------------------------------------------------------------------- >> temp.txt
find /i "Insgesamt" %Logfile% >> temp.txt  
find /i "Verzeich.:" %Logfile% >> temp.txt  
find /i "Dateien:" %Logfile% >> temp.txt  
find /i "Bytes:" %Logfile% >> temp.txt  
echo ----------------------------------------------------------------------------- >> temp.txt
find /i "Zeiten:" %Logfile%  >> temp.txt  
find /i "Beendet:" %Logfile% >> temp.txt  
type temp.txt | find /i /v "%Logfile%" > temp2.txt  
del temp.txt
ren temp2.txt temp.txt
echo. >> temp.txt
echo. >> temp.txt
ping localhost -n 9 >nul
::		------------------ Bestimmte Zeilen auslesen Ende ------------------------
::		------------------ Mailer1 Zusammenfassung versenden ---------------------
%pathblat%\blat.exe %body% -attach %Logfile% -to %mailto% -server %mailsrv% -u %mailuser% -pw %mailuserPW% -debug -timestamp -subject "%betreff%"  
goto clean
::		------------------ Letzten 5 Versionen behalten, Rest löschen! -----------
:clean
::for /f "skip=5" %%i in ('dir /b /o-D /ad /tc "%backuproot%\%MM%\????-??-??"') do ( rd /s /q "%backuproot%\%MM%\%%i") 
exit

Content-Key: 204937

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

Ausgedruckt am: 28.03.2024 um 18:03 Uhr

Mitglied: bastla
bastla 13.04.2013 aktualisiert um 17:39:38 Uhr
Goto Top
Hallo nother!

Unabhängig von der von Dir verwendeten Robocopy-Version kann ich leider die eigentliche Frage nicht beantworten - zu Deinem "Anliegen 2" hätte ich aber zumindest einen (völlig ungetesteten) Vorschlag zu bieten:
:: Robocopysicherung Nas01 incl. Mailversand
:: Zu befüllen sind die Variablen für Robocopy und dessen Logfile
::    sowie optional den Mailer
::--------------------------------------------------------------------------------
::Achtung! Ganz unten werden nur die letzten 5 Versionen behalten-----------------
::ist aber zur Sicherheit auskommentiert -----------------------------------------
::--------------------------------------------------------------------------------
@ECHO OFF & SETLOCAL
::		------------------ Codepage ändern für Umlaute im Log --------------------
chcp 1252
::		------------------ Variablen leeren --- ist unnötig, da alle unten neu erstellt werden
:: for %%i in (mydate Quelle Ziel par Logfile befehl mailsrv mailuser mailuserPW mailfrom betreff pathblat mailto body) do set "%%i=" 
::		------------------ eventuell alte vorhandene Dateien löschen -------------
if exist temp.txt del temp.txt
if exist logfile.log del logfile.log
::		------------------ allgemeine Variablen: Datum zerlegen 1 ----------------
for /F "tokens=1-3 delims=/. " %%a in ('date/T') do (  
    set "TT=%%a"  
    set "MM=%%b"  
    set "YYYY=%%c"  
)
set "mydate=%YYYY%-%MM%-%TT%"  
::		------------------ Variable Quelle ---------------------------------------
set "quelle=\\NAS-IP\Backup"  
::		------------------ Variable Zielverzeichnis mit abschließendem \ ---------
set "backuproot=f:\"  
::		------------------ lege ein Monatsordner an ------------------------------
set "ziel=%BackupRoot%%MM%\%mydate%"  
set "par=/S /MT /NP /NDL /V /FP /XJD /TS /FFT /TEE /R:1 /W:1 /XF desktop.ini Thumbs.db /XD $RECYCLE.BIN"  
::		------------------ Logfile für Robocopy ----------------------------------
::		------------------ ACHTUNG: Pfad muss vorhanden sein! --------------------
set "logfile=%BackupRoot%Logs\%mydate%.log"  
set "log=/LOG:%logfile%"  
::		------------------ Variablen für den Mailer ------------------------------
set "mailsrv=hosteurope.de:587"  
set "mailuser="  
set "mailuserPW="  
set "mailfrom=robocopy@firma.de"  
set "pathblat=C:\Programme\blat\"  
set "mailto=admin@firma.de"  
set "body=temp.txt"  
::		------------------ Attribut am 01. des Monats zurücksetzen ---------------
::		------------------ den Parameter /A durch /M ersetzen --------------------
::		------------------ Vollständige Sicherung und Attrib /A raus -------------
::		------------------ Darauffolgende Tage werden differentiell gesichert ----
if %TT%==01 (
    attrib +a "%quelle%\*.*" /s /d  
    set "par=/M %par%"  
    ping localhost -n 9 >nul
) else (
    set "par=/A %par%"  
)
::		------------------ Robocopy ----------------------------------------------
robocopy.exe "%quelle%" "%ziel%" %par% %log%  
::		------------------ Errorlevel von Robocopy überprüfen --------------------
set "err=%errorlevel%"  
if %err%==16 set "betreff=FATAL ERROR"  
if %err%==15 set "betreff=OKCOPY + FAIL + MISMATCHES + XTRA"  
if %err%==14 set "betreff=FAIL + MISMATCHES + XTRA"  
if %err%==13 set "betreff=OKCOPY + FAIL + MISMATCHES"  
if %err%==12 set "betreff=FAIL + MISMATCHES"  
if %err%==11 set "betreff=OKCOPY + FAIL + XTRA"  
if %err%==10 set "betreff=FAIL + XTRA"  
if %err%==9  set "betreff=OKCOPY + FAIL"  
if %err%==8  set "betreff=FAILED COPIES"  
if %err%==7  set "betreff=OKCOPY + MISMATCHES + XTRA"  
if %err%==6  set "betreff=MISMATCHES + XTRA"  
if %err%==5  set "betreff=OKCOPY + MISMATCHES"  
if %err%==4  set "betreff=MISMATCHES"  
if %err%==3  set "betreff=Copy successful ^& EXTRA Files deleted"  
if %err%==2  set "betreff=EXTRA Files deleted"  
if %err%==1  set "betreff=Copy successful"  
if %err%==0  set "betreff=-- Nothing to do --"  
::		------------------ Bestimmte Zeilen auslesen -----------------------------
ping localhost -n 9 >nul
 >temp.txt find /i "Gestartet:" %Logfile%   
>>temp.txt find /i "Quelle :" %Logfile%  
>>temp.txt find /i "Ziel :" %Logfile%  
>>temp.txt find /i "Optionen:" %Logfile%  
>>temp.txt echo.
>>temp.txt echo -----------------------------------------------------------------------------
>>temp.txt find /i "Der Prozess" %Logfile%  
>>temp.txt echo -----------------------------------------------------------------------------
>>temp.txt find /i "Insgesamt" %Logfile%  
>>temp.txt find /i "Verzeich.:" %Logfile%  
>>temp.txt find /i "Dateien:" %Logfile%  
>>temp.txt find /i "Bytes:" %Logfile%  
>>temp.txt echo -----------------------------------------------------------------------------
>>temp.txt find /i "Zeiten:" %Logfile%  
>>temp.txt find /i "Beendet:" %Logfile%  
 
>temp2.txt find /i /v "%Logfile%" temp.txt  
move temp2.txt temp.txt
>>temp.txt echo.
>>temp.txt echo.
ping localhost -n 9 >nul
::		------------------ Bestimmte Zeilen auslesen Ende ------------------------
if %err% leq 1 (
    REM	------------------ Mailer1 Zusammenfassung versenden ---------------------
    "%pathblat%\blat.exe" %body% -to %mailto% -server %mailsrv% -u %mailuser% -pw %mailuserPW% -debug -timestamp -subject "%betreff%"  
) else (
    REM	------------------ Mailer2 für Fehler und komplettes Logfile -------------
    "%pathblat%\blat.exe" %body% -attach %Logfile% -to %mailto% -server %mailsrv% -u %mailuser% -pw %mailuserPW% -debug -timestamp -subject "%betreff%"  
)
::		------------------ Letzten 5 Versionen behalten, Rest löschen! -----------
::for /f "skip=5" %%i in ('dir /b/o-D/ad/tc "%backuproot%%MM%\????-??-??"') do rd /s /q "%backuproot%%MM%\%%i" 
Grüße
bastla
Mitglied: rubberman
rubberman 13.04.2013 um 18:00:53 Uhr
Goto Top
Hallo zusammen.

Mir geht es ähnlich wie bastla. Habe mir die Optionen mal angesehen. Warum trotzdem leere Verzeichnisse kopiert werden ist nicht ganz zu verstehen.

Die Auswertung des Errorlevelwertes ließe sich etwas verkürzen, indem man bitweise Operationen verwendet.
Zum Testen mal mit exit /b statt robocopy, um beliebige Errorlevelwerte erzeugen zu können.
@echo off &setlocal

REM Diese Zeile erzeugt den Errorlevelwert der hinter /b angegeben ist.
cmd /c exit /b 0

set /a "return = %errorlevel%"  

setlocal EnableDelayedExpansion
set /a "n = 0"  
for %%i in ("OKCOPY" "EXTRA" "MISMATCHES" "FAILS" "FATAL ERROR") do (set "bit!n!=%%~i" & set /a "n += 1")  
if !return!==0 (set "betreff=   -- Nothing to do --") else (  
  for /l %%i in (0 1 4) do (set /a "bit=return & 1, return >>= 1" &if !bit!==1 (set "betreff=!betreff! + !bit%%i!" &if %%i gtr 0 set "mail2=goto mail2"))  
)
endlocal &set "betreff=%betreff:~3%" &%mail2%  

:logausw
REM ...

:mail1
echo mail1 %betreff%
pause
goto :eof


:mail2
echo mail2 %betreff%
pause

Grüße
rubberman
Mitglied: nother
nother 13.04.2013 um 18:58:50 Uhr
Goto Top
Danke für eure Beiträge!
Ich werde das heute Nacht mal testen!
Sieht auf jeden Fall schon mal besser aus!
Zu den leeren Verzeichnissen:
Ich nutze Windows 7 x64 Ultimate (also XP027) in Verbindung eines QNAP Nas SS439 pro.
Dieses bietet eigentlich alles was das Herz so begehrt aber leider keine Versionierung von Dateien!
Ich habe auch schon allerhand mit den Parametern von Robocopy experimentiert, aber egal wie ich es anstelle, es kommen
immer leere Verzeichnisse mit dazu...

Anyway, ist wie gesagt nicht "Kriegsentscheidend", aber nicht schön!
Danke für eure Zeit.
Werde Berichten ob alles problemlos funktioniert.

have fun

nother
Mitglied: rubberman
rubberman 13.04.2013 um 20:28:40 Uhr
Goto Top
Hallo nother.

Man könnte den Check auch in eine Funktion packen. Das macht es vielleicht einfacher.

@echo off &setlocal

REM Zur Auswertung von Robocopy (Errorlevel 0-16)
REM Diese Zeile erzeugt den Errorlevelwert der hinter /b angegeben ist (als Ersatz für Robocopy).
cmd /c exit /b 0

call :robocopycheck %errorlevel% desc
echo Is Error [0/1]: %errorlevel%
echo Description   : %desc%
pause
goto :eof
::::::::::::::::::::

:robocopycheck robocopy_errorlevel [description_variable_name]
setlocal EnableDelayedExpansion &set /a "return = %~1, err = 0" &set "txt="  
if !return!==0 (set "txt=NO CHANGE   ") else (  
  for %%i in ("OKCOPY" "EXTRA" "MISMATCHES" "FAILS" "FATAL ERROR") do (set "bit!err!=%%~i" & set /a "err += 1")  
  if !return! gtr 1 (set "err=1") else set "err=0"  
  for /l %%i in (0 1 4) do (set /a "bit=return & 1, return >>= 1" &if !bit!==1 set "txt=!bit%%i! + !txt!")  
)
endlocal &if "%~2" neq "" set "%~2=%txt:~0,-3%" &exit /b %err%  

Grüße
rubberman
Mitglied: nother
nother 14.04.2013 um 00:20:21 Uhr
Goto Top
Danke für die Mühe!
Habe eben mal die Version von bastla getestet und läuft prima (ist auch code den ich halbwegs verstehe face-wink )

Dann hatte ich mal kurz die XP010 getestet... die versteht ja den ein oder anderen Parameter nicht.
Und da war auch des Rätzels Lösung: /MT Multithread geht nicht mit XP010.

Dann habe ich im Originalscript den Paramater /MT entfernt: siehe da, Robocopy produziert keine leeren Ordner mehr!

Jetzt muss ich nur noch das ganze mal auf das NAS losjagen und die Geschwindigkeit betrachten...
Hat jemand von euch Erfahrungen gemacht, wie sehr sich der Parameter /MT auswirkt?
Daten: ca 30 GB, knapp 5000 Ordner, etwa 40 000 Dateien, Zuwachsrate etwa 0,5 bis 1 GB pro Monat, manchmal weniger...
über eine Gbit Leitung!?

Aber nochmals Danke für die Mühe!

have fun

nother