sisyphusloughs
Goto Top

Liste von Verzeichnissen auf Existenz überprüfen, ggf anlegen

elegantere Konstruktion gesucht für Wiederholungen von "if exists c:\test mkdir c:\test"

Hi,

ich habe ein Skript, mit dem eine Reihe von Verzeichnissen erstellt werden sollen, wenn sie noch nicht existieren (1). Außerdem möchte ich überprüfen, ob das Erstellen des Verzeichnisses erfolgreich war (2), und schlussendlich, ob -- falls der Ordner schon existiert, das Skript, den Ordner betreten darf (3). Die Verzeichnisse werden in Variablen zuvor festgelegt, und es kann leider sein, dass Leerzeichen enthalten sind.

So sieht mein Ansatz aus:
::Existiert das Verzeichnis?
set "DirToChk=c:\test"  
if not exists "%DirToChk%" mkdir "%DirToChk%"  
if not errorlevel 0 (
  echo '%DirToChk%' Konnte nicht erstellt werden.  
  goto :ErrorExit)
cd "%DirToChk%"  
if not errorlevel 0 (
  echo '%DirToChk%' Konnte nicht betreten werden. Geraet angeschlossen? Ist der Benutzer berechtigt?  
  goto :ErrorExit)

Statt diesen Schnipsel ungefähr 15 mal zu schreiben (sicher es geht, aber schön finde ich das nicht), wollte ich dieses Schnipsel über eins Schleife aufrufen lassen. Inspiriert von einem anderen Beitrag hier, dachte ich an eine for-Schleife.

1.
Wie gehe ich mit dem Inhalt der in-Klammer in (%order1% %ordner2% %ordner2%) um. Mir ist nicht klar, wie ich tokens und delims sicher setze, damit ich die Leerzeichen nicht zusätlziche Tokens erzeugen.

2.
Aber schon mit einem Eintrag habe ich Probleme. Zunächst hielt ich /r (weil es ja um Verzeichnisse geht) für die Lösung:
%ScriptDir%=c:\test
for /r %%i in (%ScriptDir%) do call :DirChk %%i

:DirChk
set "DirToChk=%~p1"  
if not exists "%DirToChk%" mkdir "%DirToChk%"  
if not errorlevel 0 (
  echo '%DirToChk%' Konnte nicht erstellt werden.  
  goto :ErrorExit)
cd "%DirToChk%"  
if not errorlevel 0 (
  echo '%DirToChk%' Konnte nicht betreten werden. Geraet angeschlossen? Ist der Benutzer berechtigt?  
  goto :ErrorExit)

Probleme kriege ich in Zeile 5. Nach mehreren Versuchen, bin ich aber mit meinem Latein am Ende. Ich erhalte in dieser Zeile nur Fehlermeldungen:
Zeile 3 Zeile 5 liefert Bemerkung
for/f set "DirToChk=%1" "Die Datei "c:\batch" kann nicht gefunden werden. Ok, /f steht ja für File, also sagen wir ihm, wir suchen nach Verzeichnissen
for/r set "DirToChk=%~p1" ""\batch\c:\"" ist syntaktisch an dieser Stelle nicht verarbeitbar. /r ist für Verzichnisse dokumentiert, ~p für kompletten Prad. Aber die Reihenfolge ist eigenartig.
for/d set "DirToChk=%~p1" ""\"" ist syntaktisch an dieser Stelle nicht verarbeitbar.
for set "DirToChk=%1" ""c:\batch"" ist syntaktisch an dieser Stelle nicht verarbeitbar. ok, ohne Anführungszeichen?
for set DirToChk=%1 ""c:\batch"" ist syntaktisch an dieser Stelle nicht verarbeitbar. es bleibt dabei

Mir fällt jetzt nichts mehr ein... Kann mir jemand helfen?
Gruß,
Sisiphus

Content-Key: 101914

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

Printed on: April 18, 2024 at 01:04 o'clock

Member: Sisyphusloughs
Sisyphusloughs Nov 15, 2008 at 19:56:13 (UTC)
Goto Top
OK,

ich habe einen Fehler gefunden. Und zwar hat sich in Zeile 6 ein Fehler eingeschlichen. Es sollte natürlich exist statt exists heißen. Leider konnte ich der Dos-Shell nicht entnehmen, in welcher Zeile der Fehler lag. mit for ohne weitere Option klappt zumindest der Aufruf.

Gruß, sisiphus
Member: bastla
bastla Nov 15, 2008 at 22:10:09 (UTC)
Goto Top
Hallo sisiphus!

Es gibt natürlich mehrere Möglichkeiten, die Verzeichnisliste festzulegen:

Wenn es nur wenige Verzeichnisse sind, direkt in der "for"- (ohne "/f" oder "/r") Schleife:
for %%i in (D:\EinVerzeichnis "D:\Ein anderes Verzeichnis" "D:\Das\aller\letzte Verzeichnis") do echo "%%~i"
Das geht natürlich auch, wie schon in Deinem Entwurf dargestellt, über eine Variable:
set "Dirs=D:\EinVerzeichnis "D:\Ein anderes Verzeichnis" "D:\Das\aller\letzte Verzeichnis""
for %%i in (%Dirs%) do echo "%%~i"

Ansonsten eignet sich eher eine Auflistung in einer Datei, wobei dies auch der Batch selbst sein kann (entsprechend der seinerzeit in BASIC verwendeten DATA-Zeile):
@echo off & setlocal
REM DATA D:\EinVerzeichnis
REM DATA D:\Ein anderes Verzeichnis
REM DATA D:\Das\aller\letzte Verzeichnis
for /f "tokens=2*" %%i in ('findstr /b /c:"REM DATA" %0') do echo "%%~j"  
Hier werden aus der Batchdatei (%0) alle Zeilen, welche mit "REM DATA" beginnen, herausgesucht und wie folgt zerlegt: Leerzeichen (und TAB) ist das Default-Trennzeichen, sodass "token" Nr 1 das "REM" enthält (was uns aber überhaupt nicht interessiert), "token" Nr 2 dem "DATA" entspricht und als %%i zur Verfügung stünde (brauchen wir zwar auch nicht, ist aber erforderlich zur "Abgrenzung" vom Rest) und alles Weitere in der Zeile (ohne weitere Unterteilung = mitsamt Leerzeichen) als "token" Nr 3 in %%j ankommt.

Wenn es eine externe Parameterdatei auch tut, dann zB
@echo off & setlocal
for /f "delims=" %%i in (D:\Verzeichnisse.txt) do echo "%%~i"  
wobei in diesem Fall in der Datei "D:\Verzeichnisse.txt" nur einfach je Zeile ein Verzeichnispfad (mit oder ohne umgebende Anführungszeichen) steht.
In allen Fällen sorgt die Schreibweise "%%~i" dafür, dass (durch ~) bereits vorhandene Anführungszeichen entfernt werden, aber dann auf jeden Fall (auch, wenn es vorher noch keine Anführungszeichen gab) der "fertige" Pfad von Anführungszeichen umgeben ist, womit Du ein definiertes Ergebnis erhältst.
Beim Überprüfen auf Existenz wäre noch zu beachten, dass ein "if exist" auch Dateien berücksichtigt, daher besser etwas ausführlicher (und wegen der größeren Flexibilität in einem Unterprogramm) checken:
for ... do call :ProcessDir "%%~i"  
goto :eof

:ProcessDir
if exist "%~1\" goto :OK  
if exist "%~1" (echo Datei "%~1" vorhanden - Verzeichnis kann nicht erstellt werden! & goto :eof)  
md "%~1" || (echo Fehler beim Erstellen von "%~1" & goto :eof)  
:OK
echo Verzeichnis "%~1" (jetzt) vorhanden  

:: weitere Prüfungs-/Verarbeitungsschritte

goto :eof
Noch zur Schreibweise
Anweisung1 || Anweisung2
Diese entspricht
Anweisung1
if errorlevel 1 Anweisung2
und bedeutet, dass bei einem Errorlevel größer 0 nach der Ausführung von "Anweisung1" die "Anweisung2" ausgeführt wird.

Grüße
bastla

P.S.: Mit der Verwendung der "Tabellen"-Formatierung hast Du Dir aber Mühe gegeben und das sehr schön dargestellt. face-smile
Member: Sisyphusloughs
Sisyphusloughs Nov 15, 2008 at 22:24:00 (UTC)
Goto Top
Hallo bastla,

ich bin mal wieder begeistert.

Danke auch für den Hinweis, dass "exist" auch Dateien berücksichtigt. Da wäre ich schön auf die Nase gefallen!

Nochmals Tausend Dank!
Gruß, sisiphus
Member: bastla
bastla Nov 15, 2008 at 22:25:32 (UTC)
Goto Top
Hallo sisiphus!

Freut mich, wenn's hilft. face-smile

Grüße
bastla