user340956 war der Lösung schmerzlich nahe, aber Sie wissen ja, was man über Nähe sagt…
Um es klar zu sagen, rd /s /q c:\foobar
löscht das Zielverzeichnis zusätzlich zu seinem Inhalt, aber Sie wollen nicht immer das Verzeichnis selbst löschen, manchmal wollen Sie nur seinen Inhalt löschen und das Verzeichnis in Ruhe lassen. Der Befehl deltree
könnte dies tun, aber Micrsoft hat in seiner unendlichen “Weisheit” den Befehl entfernt und ihn nicht auf Windows portiert.
Hier ist eine Lösung, die ohne Rückgriff auf Tools von Drittanbietern funktioniert. Sie ist wahrscheinlich so einfach und effizient, wie es mit einem Befehlszeilen-Skript möglich ist, anstatt direkt ein ausführbares Programm zu schreiben. Es setzt keine Umgebungsvariablen und verwendet keine Schleifen. Es ist auch so sicher wie möglich, mit Fehlerüberprüfung überall möglich, und auch so benutzerfreundlich wie möglich, mit eingebauten Dokumenten:
dt.bat
(oder dt.cmd
für die Kinder; was auch immer, ich bin alt, ich benutze .bat
):
:: dt is a Windows-compatible version of the deltree command
:: Posted to SuperUser by Synetech: https://superuser.com/a/1526232/3279
@echo off
goto start
:start
if ["%~1"]==[""] goto usage
pushd "%~1" 2>nul
if /i not ["%cd%"]==["%~1"] goto wrongdir
rd /s /q "%~1" 2>nul
popd
goto :eof
:usage
echo Delete all of the contents of a directory
echo.
echo ^> %0 DIR
echo.
echo %0 is a substitute for deltree, it recursively deletes the contents
echo (files and folders) of a directory, but not the directory itself
echo.
echo DIR is the directory whose contents are to be deleted
goto :eof
:wrongdir
echo Could not change to the target directory. Invalid directory? Access denied?
goto :eof
So funktioniert es:
- es prüft, ob ein Kommandozeilenargument übergeben wurde, und gibt Nutzungsinformationen aus und beendet sich, wenn nicht.
- Es benutzt
pushd
, um das aktuelle Verzeichnis zu speichern, dann zum Zielverzeichnis zu wechseln und alle Fehler nach nul
umzuleiten, um eine sauberere Kommandozeilenerfahrung (und sauberere Protokolle) zu erhalten.
- Es prüft, ob das aktuelle Verzeichnis jetzt mit dem Zielverzeichnis übereinstimmt, gibt eine Fehlermeldung aus und beendet sich, wenn dies nicht der Fall ist. Dadurch wird verhindert, dass der Inhalt des vorherigen Verzeichnisses versehentlich gelöscht wird, wenn der Befehl
pushd
fehlgeschlagen ist (z.B, Übergeben eines ungültigen Verzeichnisses, Zugriffsfehler usw.)
- Diese Prüfung unterscheidet nicht zwischen Groß- und Kleinschreibung, so dass sie unter Windows üblicherweise sicher ist, aber nicht für Dateisysteme, die Groß- und Kleinschreibung unterscheiden, wie sie von *nix-Systemen verwendet werden, selbst unter Windows.
- Sie funktioniert nicht mit kurzen Dateinamen (z.B. wird
C:\Users\Bob Bobson\foobar
nicht als dasselbe wie C:\Users\BobBob~1\foobar
angesehen, selbst wenn sie es tatsächlich sind). Es ist eine kleine Unannehmlichkeit, den nicht-kurzen Dateinamen verwenden zu müssen, aber es ist besser auf Nummer sicher zu gehen, besonders da SFNs nicht völlig zuverlässig oder immer vorhersehbar sind (und vielleicht sogar ganz deaktiviert werden können).
- es benutzt dann
rd
, um das Zielverzeichnis und seinen gesamten Inhalt zu löschen und leitet alle Fehler (die es mindestens einen für das Verzeichnis selbst geben sollte) nach nul
um. Einige Anmerkungen dazu:
- Da das Zielverzeichnis das aktuelle Verzeichnis ist, hat das System einen offenen Datei-Handle für dieses Verzeichnis und kann es daher nicht tatsächlich löschen, sondern bleibt so, wie es ist, was das gewünschte Verhalten ist.
- Da es erst versucht, das Zielverzeichnis zu entfernen, nachdem sein Inhalt entfernt wurde, sollte es jetzt leer sein (anders als alles, was ebenfalls offene Datei-Handles hat).
- Schließlich kehrt es mit
popd
zum vorher aktuellen Verzeichnis zurück und beendet das Skript.
(Wenn Sie möchten, können Sie das Skript mit den obigen Beschreibungen mit rem
oder ::
kommentieren).