biber
Goto Top

Workshop Batch for Runaways - Part I - Beispiel FindLongPath.Bat Bedenklich lange Pfade finden

Ein paar Batchgrundlagen für Einsteiger und Fortgeschrittene..
Mit viel Prosa und einem bisschen Praxisbezug für den kleinen Admin und die kleine Admine

:intro
Ein kleiner Workshop für alle, die vielleicht mal einen Batch mit mehr mit 10 Zeilen schreiben wollen oder müssen...Ich will hier mal versuchen, einige der CMD-Möglichkeiten transparent zu machen, die besonders den "Absolute Beginners" immer so undurchsichtig bleiben. Und trotz alledem vielleicht ein oder zwei Batches hier posten, die auch in der Praxis genutzt werden können. Nur.. wo fang ich an??? Hmmm...okay,

IF "%meinName%"=="Hase" (goto AbsoluteBloodyBeginners) ELSE goto Angeber

:AbsoluteBloodyBeginners
Batch heißt "Stapel" und eine Batchdatei enthält also mehrere Befehle, im Normalfall einen pro Zeile, die nacheinander aufgeführt werden. Welche Befehle es gibt, ist bei Eingave von "help" am CMD-Prompt zu sehen. Eingeben kann man/frau das Ganze mit einem beliebigen Editor, speichert es als Datei mit der Endung *.bat, z.B. MeinErsterBatch.bat ab und ruft es auf durch Eingabe vom "MeinErsterBatch" vom CMD-Prompt.
Variablen kann man/frau auch definieren ("SET Nickname=Biber", sie ändern ("set Nickname=Der %Nickname% aus Bremen") und auch löschen ("set NickName=")
Und es gibt, wenn auch ein wenig spartanisch, ..na ja, nicht zumindest so ganz objektorientiert, alle nötigen Kontrollstrukturen wie
- IF ..ELSE-Verzweigungen,
- FOR..IN..DO-Schleifen und
- die Möglichkeit, Unterroutinen aufzurufen (mittels "call :subxy") oder
- mit einer "GOTO :sprungmarke"-Anweisung den Batch an einer anderen Programmzeile fortzusetzen.
-"Goto :eof" beendet eine Unterroutine oder auch das ganze Programm, entspricht also in etwa dem RETURN aus anderen Programmiersprachen.
- Kommentare und Doku-Zeilen kann ich auch einfügen (Zeilenbeginn mit "REM" oder "::")

Eine Trockenübung noch für die totalen Noobs und dann was Richtiges..
Mal einfach am CMD-Prompt eingeben:
> Set meinNick=Biber
> Set meinPils=Becks
> Set derRest=Schweigen 
......(alle Inhalte können natürlich je nach Persönlichkeit geändert werden)

..spielen wir doch mal..."Set" zeigt alle Variablen, "Set mein" alle Variablen beginnend mit "mein"..
> Set 
> Set mein
> echo Mein Nick ist: %meinNick%, ich trinke %meinPils%.
> if defined meineRente (echo meine Rente ist %meineRente%) else echo MeineRente ist Undefiniert.
> FOR %i IN (meinNick meinPils meineRente derRest) DO @IF DEFINED %i SET %i
...wer bis hierhin klargekommen ist, der versteht auch den Rest.
Ach ja... das Zeichen "@" vor dem IF in der letzten Zeile unterdrückt nur die Anzeige dieses Befehls auf dem Bildschirm. Wird oft verwendet beim "@echo off" als erste Zeile in einer Batchdatei.


:Angeber
Nehmen wir mal lieber ein Beispiel aus dem Leben, ehe das zu trocken wird.. neulich gab es mal eine Herausforderung hier im Forum, die sich auch per Batch lösen läßt.. wir tasten uns mal laaangsam ran.

1) Die Aufgabe
Unter Pfadtiefe auslesen (von Kollege netboarder) steht:
"...Meine Aufgabe ist es einen Report zu erstellen in dem alle Verzeichnisse bzw. Pfade aufgelistet werden die eine Pfadtiefe > 200 Zeichen enthalten..." , eine Frage aus der Praxis, die sich nur auf drei Arten lösen lässt - mit Extra-Tools, durch Praktikanten oder eben mit den Windows-Bordmitteln, also Batch oder Script.
( weiterer Querverweis zu dem Thema Pfadlänge: Pfadtiefe unter verschiedenen Betriebssystemen)
Okay,...mal überlegen, bevor ich anfange, sollte ich am besten einen Plan haben.

2) Den Plan entwickeln .. oder: was weiß ich, was brauche ich und was sollte ich vorher überlegen?
"..einen Report erstellen..".. was will der? Ziel soll doch sein, alle Verzeichnisse mit Pfadlänge größer gleich nnn Zeichen in einer Text-Datei zu haben.. Daraus folgt doch, ich brate mir einen Batch zusammen, der soll heißen *grübel*... FindLongPath.bat, weil ich ja so gut ausländisch kann face-wink und der soll zwei Parameter haben, nämlich "Laufwerk/Pfad" und "Pfadlänge" und die nenne ich *grübelgrübelgrübel*.. ich nenne die p1 und p2
*strahl* und dieser Report soll heißen..am besten so, dass der Name etwas aussagt, also am Besten "f:_PfadeÜber200.txt", wenn nach Pfaden mit Länge größer 200 auf Laufwerk F: gefragt wird.., oder am besten noch den Computernamen dazu, wenn es ein Netzwerk ist.. also "Server0815_f:\_PfadeÜber200.txt" oder so... Hmm, da sind dann aber unerlaubte Zeichen drin.. na, aber sinngemäß geht das. Vielleicht "Server0815_f$_PfadeGTR200.txt" ..lieber auch keine Umlaute.
Dann kann er den aufrufen mit "FindLongPath F: 200" oder "FindLongPath d:\temp 50" zum Testen. und wenn er keinen Parameter eingibt, dann setze ich einen Default. Und wenn ich weiß, mit welchen Parametern ich etwas tun soll und wohin ich es schreibe.. dann suche ich also diese langen Pfade..
*grübel*
Ich suche Verzeichnisse auf Laufwerk X: mit einer bestimmten Pfadlänge, hmmmm.. das ist doch eine Untermenge ALLER Verzeichnisse auf Laufwerk X, und die prüfe ich dann auf ihre Länge ..wie bekomme ich denn alle Verzeichnisse? Ach ja.. das kann ich mit DIR abfackeln. Ich schreibe alle Verzeichnise in eine temporäre Textdatei und dann alle mit der großen Pfadlänge in diese endgültige Reportdatei.

Okay - zusammengefasst, ich habe
FindLongPath.bat (den Namen der Batchdatei) und als Parameter/Variablen
%1 (den Parameter "Laufwerk/Pfad") .... daraus leite ich mir meine Variable p1 ab
%2 (den Parameter "zu prüfende Länge")....daraus leite ich mir meine Variable p2 ab
Ich brauche als als Arbeitsvariablen p1, p2, Reportdatei, Tmpdatei
Die Namen der Reportdatei und der temporären Datei kann ich aus p1 und p2 ableiten.. los gehts.

Und ich will den Batch während der Entstehung "debuggen" können, denn der funktioniert bestimmt nicht beim ersten Mal. Dazu baue ich noch eine DebugShow_vars-Unterrotine ein. Und eine Cleanup-Routine auch. Der Batch besteht also aus den Unterroutinen "ParamCheck", "DebugShow_vars", "Cleanup" .. und einem Hauptteil hoffentlich. Let's go.
Wer diese "Debug-Features" nutzen will, muss VOR dem Aufruf des Batches eingeben
"Set DebugMyBatches=42"

3) Der Batch ...erster Wurf ( Version 0.01 Beta ) ->6.1.2007 0.03 Beta
::---------begin ofFindLongPath.bat -------
:: Aufruf FindLongPath [Lw:/Pfad] [Pfadlänge] -- Default Lw:/Pfad=%temp% -- Default Pfadlänge = 50
@ECHO off & SETLOCAL ENABLEEXTENSIONS
SET usedvars=tmpdatei reportdatei p1 p1masked p2 x YN PAUSE_D ECHO_D 
if Defined DebugMyBatches ((set ECHO_D=@ECHO) & (set PAUSE_D=pause) ) else ( set ECHO_D=REM)
REM call :Debugshow_vars "Am Start der Batchdatei" ...bei Bedarf das REM entfernen  
CALL :paramcheck %1 %2
:: Nicht einfach weiterlesen... hast Du geguckt, was in :paramcheck passiert???
DIR %p1% /aD /b /s >%tmpdatei%
IF exist "%reportdatei%" del "%reportdatei%"   
SET /a p2=%p2%-1
SETLOCAL EnableDelayedExpansion
FOR /F "delims=" %%i in (%tmpdatei%) do (set "x=%%i") && if "!x:~%p2%,10!" GTR "@" @echo %%i >>%reportdatei%  

IF EXIST "%reportdatei%" (  
     ECHO Report wurde gespeichert als %reportdatei%.   
     ECHO - Reportdatei vom %date% -- Alle Verzeichnisse ^>%p2% auf %p1% -->>"%reportdatei%"   
     ECHO - Reportdatei "%reportdatei%" -->>"%reportdatei%"  
     SET /p YN="Auf %p1% wurden Pfade mit Länge größer %p2% gefunden. Anzeigen (J/N?) "  
     IF /i "!YN!"=="J" TYPE "%reportdatei%" |MORE       
) ELSE (
     ECHO Keine Pfade länger als %p2% Zeichen im Pfad %p1% gefunden.
)
ENDLOCAL
CALL :DebugShow_vars
CALL :cleanup
GOTO :eof
:: -------------------
::::::::::::  ParamCheck ... Hier werden die Parameter %1 und %2 geprüft daraus %p1% und %p2% abgeleitet.
:: Param 1 : Laufwerksbuchstabe oder Verzeichnis; Default %temp%
:::::::::::: Dieser Parameter wird als Substring in den Variablen %tmpdatei% und %reportdatei% verwendet 
:::::::::::: Dafür werden ":" und "\" durch "$" und"_" ersetzt, um einen gültigen Dateinamen zu bilden. 
:::::::::::: dazu Zwischenspeicherung in Variable %p1% und %p1masked% 
:::::::::::: Syntax dazu siehe SET /? und dort.. %PATH:str1=str2%
:: Param 2:: zu prüfende Länge der Verzeichnisse ... Default 50

:ParamCheck
IF (%1)==() (SET p1=%temp%) ELSE (SET p1=%1)
REM nächste Zeile bipede-Variante - siehe unten
IF (%1)==() (SET p1=C:) ELSE (SET p1=%1)
IF (%2)==() (SET /a p2=50 ) ELSE (SET /a p2=%2)
SET p1masked=%p1::=$%
SET p1masked=%p1masked:\=_%
%ECHO_D% p1-^>p1masked ist %p1%-^>%p1masked%; p2 ist %p2%
SET "tmpdatei=%temp%\%computername%_%p1masked%_All.lst"  
SET "Reportdatei=%temp%\%computername%_%p1masked%_PfadeGTR%p2%.lst"  
CALL :Debugshow_vars "Nach Var-Setzen"  
goto :eof
:: --------------------
:DebugShow_vars
IF DEFINED DebugMyBatches (
SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%i IN (%usedvars%) DO (ECHO [%~1] Variable %%i="!%%i!" )   
ENDLOCAL
PAUSE
)
GOTO :eof
:: -----------------
:cleanup
%ECHO_D% in Subroutine :Cleanup
IF EXIST "%tmpdatei%" (del "%tmpdatei%") & %ECHO_D% Datei %tmpdatei% wird gelöscht.  
FOR %%i IN (%usedvars% usedvars) DO @IF DEFINED %%i (
  (IF DEFINED DebugMyBatches echo %%i wird freigegeben) & (SET %%i=))

GOTO :eof
::---------End of FindLongPath.bat -------

-- Fortsetzung bei Interesse hier--
Workshop Batch for Runaways - Part II - Ein bisschen Handwerkszeug
Workshop Batch for Runaways - Part III - Datums- und Zeitvariablen im Batch
...und immer gern empfohlen
Tutorial zur FOR-Schleife von Friemler

Frank / der Biber aus Bremen

Content-Key: 14379

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

Printed on: July 17, 2024 at 19:07 o'clock

Member: bipede
bipede Jan 05, 2007 at 13:15:23 (UTC)
Goto Top
Hi,
ich wollte das Batch-Skript gerade verwenden. Um keine Parameter übergeben zu müssen habe ich einfach den Default-Wert für den Pfad zu "C:" geändert:
------------------------------------
:ParamCheck
IF (%1)==() (SET p1=C:) ELSE (SET p1=%1)
------------------------------------
Es klappt leider nicht, es heißt nur "Gerät ist nicht bereit". Das Spript habe ich vom Desktop aus gestartet (Doppelklick).

Irgendein Tipp? Ich verwende XP auf einem Samsung R40 Laptop.

Grüße
manu
Member: Biber
Biber Jan 05, 2007 at 14:07:24 (UTC)
Goto Top
Moin bipede,

willkommen im Forum.
Ich habe noch einen Bugfix nachgezogen, der im Nachfolge-Tut "Workshop Batch for Runaways Part II - Ein bisschen Handwerkszeug" beschrieben wurde. Ich hatte mich damals nicht getraut, diesen Beitrag zu editieren, weil ein anderes meiner Tuts nach dem Editieren gar nicht mehr angezeigt wurde.

Ist jetzt oben eingebaut und nun sollte es laufen.

Okay, das sagen alle. face-wink
Wenn also nicht: Dann rufe das Skriptchen bitte über den CMD-Prompt auf und setze vorher
Set DebugMyBatches=wattDuWillst

Dann schauen wir weiter.

Grüße
Biber
Member: bipede
bipede Jan 05, 2007 at 14:34:45 (UTC)
Goto Top
Hi, Danke. Die Reportdatei wird auf Laufwerk D gespeichert, das ist bei mir ein DVD-Laufwerk. Nachdem ich folgende Änderung vorgenommen habe

SET "Reportdatei=c:\%computername%_%p1masked%_PfadeGTR%p2%.lst"

klappt es. Die Reportdatei wird jetzt einfach im C-Laufwerk gespeichert.

Eher unwichtig:
Darf man denn die Endung in "txt" umändern?

Grüße und vielen Dank von der Dummie-Front
manu
Member: Biber
Biber Jan 05, 2007 at 14:43:50 (UTC)
Goto Top
Na, dann bin ich beruhigt, bipede,

Eher unwichtig:
Darf man denn die Endung in "txt" umändern?
Klar, die Endung der Report-Datei ist hier vollkommen unwichtig.
Das einzige, was mit der gemacht wird, ist ein TYPE %reportdatei% .. und da ist die Endung beliebig.
Die Endung wäre nur dann von Belang, wenn Du die Datei über "Start %reportdatei%" mit der "richtigen" bzw. zugeordneten Applikation starten würdest... also eine .txt-Datei mit NotePad.exe öffnen oder eine Datei mit der Endung .HTML über den Explorer.

Grüße
Biber
[Edit] Einen Tag später....
Noch mal über den gemeldeten Bug nachgedacht und ...*vornKoppKlatsch* im Source stand tatsächlich:
SET "Reportdatei=d:\temp\%computername%_%p1masked%_PfadeGTR%p2%.lst"
-statt-
SET "Reportdatei=%temp%\%computername%_%p1masked%_PfadeGTR%p2%.lst"
D:\Temp entspricht auch tatsächlich meinem %temp%-Verzeichnis, aber bei anderen kann ja das Laufwerk D: auch ein CD-Laufwerk sein.
Na ja, nun ist es oben die Version 0.03.
Danke nochmal an bipede.
[/Edit]
Member: AD
AD Feb 12, 2007 at 19:25:52 (UTC)
Goto Top
Hallo Biber,

klasse Tutorial, habe auch ein "Big Problem", es wurde ausversehen in ein Verzeichnis mehere Unterverzeichnisse erstellt ohne weiteren Inhalt. Nun ist die Tiefe der Verzeichnisse schon so tief, dass die Größe von 256 Zeichen überschritten wurde. Hast du oder ein andere eine Idee wie ich diese Verzeichnisse gelöscht bekomme? Da es sich ja um Windows 2003 Server handelt ist es ja ab 256 Zeichen im Explorer vorbei, gibt es eine möglichkeit per script diese Verzeichnisse zu löschen (D:\public\Allgemein\Backup\Backup\Backup\Backup\Backup\Backup\Backup\Backup)?

Danke im Vorraus

Gruß Michael
Member: Biber
Biber Feb 12, 2007 at 20:03:27 (UTC)
Goto Top
Moin AD,

im Explorer ist beim Anlegen und beim Hin-Kopieren bei 256 Zeilen Schluss, beim Lesen und beim Zurückkopieren bei 254.. face-wink
Wenn Du zwischenzeitlich Programm aus der xxACLs-Schiene benutzt - die hauen bei 250 bis 253 Zeichen ins Mett...

Aber das löst Dein Problem ja nicht.

Also, wenn Du auf dem Server agieren kannst mit den nötigen Rechten, dann ist es einfach.
Rezept ist simpel: Den langen Pfad kürzer machen.
Zwei Strategien:
- > die simpelste: Mach ein Subst auf einen Teilpfad
Subst w: D:\public\Allgemein\Backup\Backup\Backup\Backup
rd /s /q w:\Backup

-> oder (wenn in den tieferen Ebenen noch Daten sein sollten)
Dann benenn die Teil-Unterordner per Batch oder von Hand um von "Backup" in "B".

Übrigens - in den grafischen Oberflächen entstehen interessante Effekte bei so langen Pfaden, gell? *g

Gruss
Biber
P.S. Wenn Du öfters Kommentare von mir liest, wirst Du merken, dass ich die Formulierung "Danke im Vorraus" total lieb habe.... face-wink
Member: AD
AD Feb 12, 2007 at 20:22:27 (UTC)
Goto Top
Hallo Biber,

danke für deine schnelle Antwort. Ich werde es sofort probieren. Deine Vorliebe was die beiden Worte betreffen, habe ich in einen von mir vorher verfassten Kommentar eingebracht. Dieser ging mir aber leider wegen einer längeren Pause (meine kleine Tochter) verloren. m der zweiten Fassung habe ich Ihn dann irgendwie vergessen. Ich hoffe du kannst mir verzeihen.


Danke im Vorraus face-smile

Gruß AD
Member: TuXHunt3R
TuXHunt3R Jun 25, 2007 at 10:29:34 (UTC)
Goto Top
Guten Tag

1. Danke an den Biber für diesen Batch. Ich wollte schon lange so etwas realisieren und habe hier endlich einen Denkansatz gefunden.

2. Ich habe mir erlaubt, den Batch ein bisschen besser zu strukturieren und zu entschlacken. Da die Version von Biber fast gar nicht auskommentiert war, habe ich diese Ergänzungen vorgenommen

Hier meine Version des Batches:

::*****************************************************************
::* LongPath.bat                                                   *
::* ===========                                                   *
::* Listet extrem lange Pfade                                     *
::* auf einem Laufwerk oder Share auf                             *
::* Herzlichen Dank an Biber (Forenmitglied bei administrator.de) *
::* History:                                                      *
::* 20.06.2007 - New Batch                              *
::* 25.06.2007 - Batch finalisiert                      *
::*****************************************************************

@ECHO off
cls

::-----------------------------------------------------------------
::Parameter-Abfragen

if "%1"=="" goto manual  
if "%1%"=="" goto Manual  
if "%1%"=="?" goto Manual  
if "%1%"=="/?" goto Manual  
if "%1%"=="-?" goto Manual  
if "%1%"=="-h" goto Manual  
if "%1%"=="--h" goto Manual  
if "%1%"=="-help" goto Manual  
if "%1%"=="--help" goto Manual  
if "%1%"=="help" goto Manual  

::Setze Variablen
SET usedvars=tmpdatei reportdatei p1 p1masked p2 x YN PAUSE_D ECHO_D 

set p1=%1
::Falls keine Längenangabe gemacht wird, wird die Länge auf 256 gesetzt
IF (%2)==() (SET /a p2=256 ) ELSE (SET /a p2=%2)
::Ersetze Zeichen, die nicht in Dateinamen dürfen (/\:*?"<>|) durch andere 
SET p1masked=%p1::=$%
SET p1masked=%p1masked:\=_%
::%ECHO_D% p1-^>p1masked ist %p1%-^>%p1masked%; p2 ist %p2%
::Setze Variablen für die Logfiles
SET "tmpdatei=%systemroot%\temp\longpath\dir_%p1masked%.txt"  
SET "Reportdatei=%systemroot%\temp\longpath\report_%p1masked%_Pfade-groesser-%p2%.lst"  
::-----------------------------------------------------------------

::-----------------------------------------------------------------
::Vorhergehende Aufgaben

::Überprüeft, ob bereits ein Ordner für die Logfiles existiert
if exist %systemroot%\temp\longpath (
rmdir /s /q %systemroot%\temp\longpath
)

::Erstelle Ordner für Logfiles
mkdir %systemroot%\temp\longpath
::-----------------------------------------------------------------

::-----------------------------------------------------------------
echo Longpath.bat
echo ==========
echo.
::Überprüft, ob der angegebene Ordner existiert. Falls ja, listet der Batch alle Pfade auf

If not exist %1 (
echo Der Pfad %1 existiert nicht!
echo.
goto end
) else (
echo Die Pfadlaengen-Abfrage von %1 wurde gestartet...
echo.
dir /s /b  %1 >>%tmpdatei%
echo Index wurde erstellt, Pfade werden gefiltert...
)
::-----------------------------------------------------------------

::-----------------------------------------------------------------
::Filtert das File %tmpdatei% nach langen Pfadnamen
SETLOCAL EnableDelayedExpansion
FOR /F "delims=" %%i in (%tmpdatei%) do (set "x=%%i") && if "!x:~%p2%,10!" GTR "@" @echo %%i >>%reportdatei%  

if exist %reportdatei% (
echo. >>%reportdatei%
echo ---------------------------- >>%reportdatei%
echo Report des Batches "Longpath" >>%reportdatei%  
echo ----------------------------- >>%reportdatei%
echo Ausgefuehrt am %date% von %username% >>%reportdatei%
echo Ordner: %p1% >>%reportdatei%
echo Gefilterte maximale Pfadlaenge: %p2% >>%reportdatei%
echo In %1 wurden Pfade mit Laenge groesser %p2% gefunden!
choice /c:JN Sollen die Ergebnisse in Notepad angezeigt werden?
if errorlevel 1 notepad %reportdatei%
) else (
echo In %p1% wurden keine Pfade mit Laenge groesser %p2% gefunden!
echo.
)
ENDLOCAL
::-----------------------------------------------------------------

goto end



:Manual
echo Longpath.bat
echo ==========
echo.
echo Listet alle Pfade auf, die laenger sind als die angegebene Laenge.
echo.
echo.
echo Starte Batch folgendermassen:
echo Fatpath Pfad Pfadlaenge
echo.
echo.
echo Beispiele:
echo Longpath \\server\share$\ordner1\ordner2 200
echo.
echo ==^> Listet alle Pfade in \\server\share$\ordner1\ordner2 auf,
echo      die laenger als 200 Zeichen sind.
echo.
echo Falls nicht angegeben wird, wie lange der Pfad sein darf,
echo geht Longpath davon aus, dass eine Pfadlaenge von 256 Zeichen gemeint ist.
echo.
echo Hier einige Angaben zu der maximal erlaubten Pfadlaenge von verschiedenen Dateitypen:
echo .doc --^>  
echo .xls --^> 218 Zeichen
echo .ppt --^>
echo .pdf --^>
echo .pst --^>
echo.                           
                                    
:end
Member: Biber
Biber Jun 28, 2007 at 10:06:54 (UTC)
Goto Top
Moin TuXHunt3R,

sorry, ich habe Deinen Kommentar eben erst entdeckt.

Erstmal danke für das Wiederbeleben des FindlongPath-Beispiels.

Und Recht hast Du... der war ja auch von mir eher ein bisschen verspielt und for educational purposes angelegt.
Und eigentlich nicht als wartbarer Produktivbatch.

Von daher finde ich Deine Variante sinnvoll und bedanke mich dafür.

Ändern/prüfen würde ich noch:

..
if "%1"=="" goto manual  
if "%1%"=="" goto Manual  
if "%1%"=="?" goto Manual  
if "%1%"=="/?" goto Manual  
if "%1%"=="-?" goto Manual  
if "%1%"=="-h" goto Manual  
if "%1%"=="--h" goto Manual  
if "%1%"=="-help" goto Manual  
if "%1%"=="--help" goto Manual  
if "%1%"=="help" goto Manual  

-> die ganzen Zeilen mit dem Prozentzeichen nach der "1" kämen auch ohne das letzte %-Zeichen aus.

Und das "goto end" und die Sprungmarke ":end" würde ich aus heutiger Sicht durch ein "goto :eof" (ohne Sprungmarke) ersetzen.

Viele Grüße
Biber
Member: TuXHunt3R
TuXHunt3R Jan 16, 2008 at 19:33:25 (UTC)
Goto Top
@ Biber

-> die ganzen Zeilen mit dem Prozentzeichen nach der "1" kämen auch ohne das letzte %-Zeichen aus.

Da hast du schon recht, es reicht auch ein %1

Und das "goto end" und die Sprungmarke ":end" würde ich aus heutiger Sicht durch ein "goto :eof" (ohne Sprungmarke) ersetzen.

Das goto :eof brauche ich eben häufig bei For-Schleifen, nach dem goto :end packe ich bei manchen Batchs noch ein kleines echo à la "echo Coded 2008 by TuXHunT3R" oder so was ähnliches hin. Ist mehr eine Stilfrage.
Mitglied: 6741
6741 Feb 10, 2008 at 18:39:03 (UTC)
Goto Top
hi

klasse Script Biber ...

könntest du eine Abfrage für einen Server einbauen ...???

Also:

Geben sie den Server an .. zb

\\10.10.10.10\d$

und dann sollte das Script die Freigabe absuchen ...

gruß
Member: TuXHunt3R
TuXHunt3R Feb 10, 2008 at 22:20:59 (UTC)
Goto Top
@6741


Schau dir mal meine Version sonst noch an. Es funktioniert auch mit UNC-Pfaden....
Mitglied: 6741
6741 Feb 11, 2008 at 08:42:27 (UTC)
Goto Top
Hi TuXHunt3R

ich habe das Script, so wie es ist, gestern getestet. Es blinket nur eine Dos Box auf, aber so passierte nichts. Muss man noch etwas berücksitigen? Wo stehtr der Pfad für die UNC Angabe, unter?

gruß
Member: TuXHunt3R
TuXHunt3R Feb 11, 2008 at 19:08:17 (UTC)
Goto Top
Du musst das Script aus der CMD-Konsole aus aufrufen. Wenn du es einfach doppelklickst, wird nur die Hilfe ausgegeben (und das auch nur für <1sek.)
Member: bipede
bipede Dec 08, 2008 at 21:35:46 (UTC)
Goto Top
Hallo! Choise gibt es wohl unter XP nicht mehr - sonst ist das Skript hier klasse.

Beste Grüße
manu
Member: bipede
bipede Dec 08, 2008 at 21:37:02 (UTC)
Goto Top
Hallo! Choise gibt es wohl unter XP nicht mehr - sonst ist das Skript hier klasse.

Beste Grüße
manu

PS: Sorry für den Doppel-Post - irgendwie ist der erste Kommentar viel zu weit oben.
Member: TuXHunt3R
TuXHunt3R Dec 11, 2008 at 20:49:05 (UTC)
Goto Top
Hallo bipede

Choice ist ein Exe-File, welches sich im XP-Resourcekit befinden sollte. Einfach mal googlen.
Member: bipede
bipede Dec 11, 2008 at 22:59:26 (UTC)
Goto Top
Hallo und Danke - habe es mal runtergeladen.

Grüße!
manu

Nachtrag: Habe es installiert - aber unter C:\Programme\Support Tools gibt es choice.exe nicht - anyway - auf http://winsupport.org/utilities/freedos-choice.html gab es ne Freeware die wohl auch funktioniert.
Member: kleinerbub
kleinerbub Jan 17, 2009 at 00:12:32 (UTC)
Goto Top
Hi Biber,
danke für die Batch (ich weiß, is schon alt, aber aus aktuellem Anlass bin ich drüber gestolpert)!

Ich hätt mal noch ne Spezialfrage für die Profis unter den Batchern:

Ich hab n Skript, welches nacheinander Netzlaufwerke zu verschiedenen Servern verbindet und Verzeichnisse darüber sichert. Nun kam es vor, dass die maximale Pfadlänge überschritten wurde, wobei xcopy einfach abbricht (nebenbei such ich noch ne Möglichkeit diese Fehler zu loggen, weil man das sonst garnich gleich mitkriegt).

Jetz wärs cool, wenn ich vorher die Pfade auf Länge überprüfen lassen könnte und die zu langen Pfade in Kurzform (Option /N) kopieren lasse.

Wäre nett, wenn sich einer mit mir auf Lösungssuche begibt...


edit: Vielleicht mal noch ein Auszug aus meinem Sicherungsscript:
if exist N:\nul net use /delete N:

set param=/C /E /F /H /R /Y
set info=PW /user:User
set ID=1

:Server1
set server=server1
set Verz1=\d$
set Ziel1=BACKUP\server1
GOTO Server_Start

:Server2
set server=server2
set Verz1=\d$
set Verz2=\e$
set Ziel1=BACKUP\server2_D
set Ziel2=BACKUP\server2_E
GOTO Server_Start

:Server3
GOTO Complete

:Server_Start
net use N: \\%server%%Verz1% %info%
IF NOT %errorlevel% == 0 (
	echo Die Netzwerkverbindung zu %server%%Verz1% konnte nicht hergestellt werden.>> C:\DS\Logfiles\%logname%.log
) ELSE (
	xcopy N:\*.* E:\%1\%Ziel1%\*.* %param%
	net use /delete N:
	IF NOT %errorlevel% == 0 echo Fehler beim Kopiervorgang.>> C:\DS\Logfiles\%logname%.log
)

IF not defined Verz2 (
	GOTO Server_Done
) ELSE (
	net use N: \\%server%%Verz2% %info%
	IF NOT %errorlevel% == 0 (
		echo Die Netzwerkverbindung zu %server%%Verz2% konnte nicht hergestellt werden.>> C:\DS\Logfiles\%logname%.log
	) ELSE (
		xcopy N:\*.* E:\%1\%Ziel2%\*.* %param%
		net use /delete N:
		IF NOT %errorlevel% == 0 echo Fehler beim Kopiervorgang.>> C:\DS\Logfiles\%logname%.log
	)
)

:Server_Done
set Verz1=
set Verz2=
set Ziel1=
set Ziel2=
set param=/C /E /F /H /R /Y
set /a ID=%ID%+1
GOTO Server%ID%


:Complete
if exist N:\nul net use /delete N:
Member: Biber
Biber Jan 17, 2009 at 13:34:25 (UTC)
Goto Top
Moin kleinerbub,

danke für das Feedback.
Deine Fragen möchte ich ein bisschen anders beantworten, als Du vielleicht erhofft hast...

a) XCopy-Abbrüche und XCopy-Log...
Hmmja, gibt es laut XCopy-Hilfe alles, auch einen so genannten "restartable mode" und ein "mach weiter bei Fehlern"... aber:
  • eine oberflächliche Suche im Netz nach "xcopy Fehler" oder "xcopy bugs" liefert definitiv genug, um XCopy aus allen Mach-mir-ein-Serverbackup-Phantasien zu verbannen. Nimm Robocopy.exe (oder professionelleres).
Was Robustheit, Logging und Parametrisierbarkeit angeht hätte ich aber auch gegen RoboCopy keine Bedenken.

b) Pfade kürzen und als kurze Namen kopieren (/N-Option)
Never. No way. Was nützt Dir eine tägliche, stündliche oder atomzeitgenaue Serversicherung, bei der Dir Detailinfos wie Pfad- und Dateinamen verloren gehen? No no no...

c) falls Du nur zwei Minuten Aufwand investieren willst und "erstmal" bei XCopy bleiben möchtest, dann wäre meine Strategie und meine Empfehlung wie folgt:
  • im Moment liest Du die Quell-Pfade+Dateinamen von einem Laufwerk "N:\". Dort kannst Du alles lesen (keine zu langen Pfade etc)
  • im Moment kopierst Du in ein Zielverzeichnis "xcopy N:\*.* E:\%1\%Ziel1%\*.* , also ausführlich geschrieben ein Unterverzeichniszweig, der 20 oder 25 Zeichen länger ist als die Länge des Quellpfades (der ist ja "N:\")
  • also: Wenn Du einen Pfad kopierst, der exakt genauso lang ist wie der (problemlos lesbare) Quell-Pfad, dann ist doch kein Problem mehr zu erwarten.
  • Also mache folgendes: Suche Dir einen freien Lw-Buchstaben (meinetwegen Z: wie Ziel).
  • Und definiere das Zielverzeichnis mit SUBST.exe jeweils als logisches Laufwerk Z:.

Beispiel in Deinem Schnipsel:
.....
:Server_Start 
net use N: \\%server%%Verz1% %info% 

IF NOT %errorlevel% == 0 ( 
	echo Die Netzwerkverbindung zu %server%%Verz1% konnte nicht hergestellt werden.>> C:\DS\Logfiles\%logname%.log 
) ELSE ( 
      REM Erstes Ziel-Verz trennen+neu zuordnen
      IF Exist Z:\ subst Z: /D 
      Subst Z: "E:\%1\%Ziel1%"  
      xcopy N:\*.* Z:\*.* %param% 
....
)

REM für %Verz2%, %VerzN% analog. Lw Z: trennen+neu zuordnen
..

Ein weiterer präventiver Schritt sollte allerdings sein, mit Skript und mit Deinen Endusern zusammen mal hin und wieder die "bedenklich langen Dateinamen" zu suchen - mit willkürlicher Max-Längen-Vorgabe von Dir. Und die gemeinsam auf kürzere Pfade/Namen zu bringen. Keine automatische Verstümmelung durch /N oder so was.

Grüße
Biber
Member: FrankD
FrankD Jul 20, 2009 at 08:58:34 (UTC)
Goto Top
Hallo zusammen,

ich bin auf diesen Thread gestoßen, da mich folgendes Problem zwickt:

Ich habe als NAS-Platte im Netzwerk eine Buffallo Linkstation Mini mit einem RAID1 Verbund aus zwei 500er Platten. Da gab's neulich Probleme, jedenfalls wollte ich an deren USB-Port eine 500er 2,5"-HDD anhängen und ein Backup machen. Das dauert ewig und Recherchen auf der Herstellersite ergaben, dass ab einer Pfadtiefe von 120 Zeichen es möglicherweise Probleme geben könne die eben genau zu diesem langsamen Backup führten.

So, jetzt suche ich ein Programm oder eine Batchdatei die mir die Anzahl der Zeichen im Pfad auswirft, denn auf der NAS habe ich - ordnungsliebend - natürlich verschachtelt und sortiert.

Mein Problem bei Euch: Ich verstehe nicht wirklich alles. Ich habe z.B. die sehr übersichtliche Batch von TuXHunt3R in den Editor kopiert und als zeichen.bat gespeichert. Die starte ich im CMD-Fenster und habe nun das Problem, wie ich den Pfad angeben soll.

Beispiel: Die Batch liegt bei mir auf D: - überprüfen will ich H: (eine USB-HDD), dann gebe ich ein "test \\h:" - das funktioniert nicht, will ich H:\Dateiablage überprüfen, so gebe ich ein "test \\h:\Dateiablage", auch hier meckert die Batch, dass der Pfad nicht existiert.

Auf der NAS, der ich per Netzlaufwerk den Laufwerksbuchstaben S: zugewiesen habe, dasselbe Problem.

Was mache ich verkehrt? Ich bin in DOS nicht mehr wirklich sattelfest.

Gruß,
Frank
Member: TuXHunt3R
TuXHunt3R Jul 20, 2009 at 12:46:31 (UTC)
Goto Top
Hallo Frank

Da hast du etwas falsch verstanden. Es gibt bei Windows grundsätzlich zwei Arten, wie Pfade angegeben werden können.

1.) Mit UNC-Pfaden für den Zugriff auf Netzwerkfreigaben: \\server\freigabe$
2.) Lokale Laufwerke, z.B. H:\Ordner1

In deinen Fall kannst du als Pfad einfach folgendes angeben, dann solte es funktionieren:
H:\

Die ganze Zeile sähe dann bei dir folgendermassen aus:
zeichen.bat H:\ 120
Member: FrankD
FrankD Jul 21, 2009 at 12:08:15 (UTC)
Goto Top
WOW! Vielen Dank, hat wunderbar geklappt!

Danke,
Frank
Member: nosa01
nosa01 Jun 08, 2010 at 09:26:04 (UTC)
Goto Top
Danke, genau dieses Script habe ich gesucht

Gruß

Norbert