2009-02-18 4 views
9

Wir haben ein Batch-Skript, das Dateien (del) und Verzeichnisse (rd) entfernt. Kann jemand die Ausführung des Skripts anhalten (fehlschlagen), wenn eine dieser Löschanweisungen fehlschlägt? Sie können fehlschlagen, wenn eine Datei/ein Verzeichnis von Windows gesperrt wird. Vielen Dank.So stoppen Sie Batch-Skript bei del Fehler

aktualisieren

Statements Ich verwende:

Del: del *.* /S /Q

RD: FOR /D %%G in (*) DO RD /s /q %%G

Antwort

12

Zum Löschen der Datei s, können Sie zuerst versuchen, ren (umbenennen) die Datei. ren wird ERRORLEVEL auf 1 setzen, wenn die Datei gesperrt ist. Fügen Sie Anführungszeichen um Dateiname hinzu.

@echo OFF 

:: Delete all files, but exit if a file is locked. 
for %%F in (*.*) do (
    @echo Deleting %%F 
    ren "%%F" tmp 2> nul 
    if ERRORLEVEL 1 (
     @echo Cannot delete %%F, it is locked. 
     exit /b 1 
    ) 
    del tmp 
) 

Ich vermute, dass Sie in der Lage sein, um die gleiche Sache für Verzeichnisse zu tun, aber ich kann nicht scheinen, um herauszufinden, wie man ein Verzeichnis gesperrt zu bekommen, so kann ich testen. Folgendes könnte funktionieren:

:: Remove all directories, but exit if one is locked. 
FOR /D %%G in (*) DO (
    @echo Removing %%G 
    ren "%%G" tmpdir 2> nul 
    if ERRORLEVEL 1 (
     @echo Cannot remove %%G, it is locked 
     exit /b 1 
    ) 
    RD /s /q tmpdir 
) 
+1

Dies funktioniert nicht zum Ausführen von Prozess-Image-Datei. Wenn Sie 'notepad.exe' starten, können Sie es erfolgreich umbenennen, aber Sie können seine Bilddatei nicht löschen. Gleiches gilt für geladene DLLs. – wqw

+1

Sie können ein Verzeichnis gesperrt bekommen, indem Sie ein cmd-Fenster darin öffnen ... –

3

EDIT: rechts, del so nicht die ERRORLEVEL richtig eingestellt ist. Siehe ERRORLEVEL on DEL und Windows delete command can fail silently

PREVIOUS (falsch) SOLUTION

Sie sollten die errorlevel überprüfen.

Zum Beispiel:

del file.txt 
if errorlevel 1 goto FAIL 
:PASS 
echo Worked! 
goto :END 

:FAIL 
echo Failed! 
exit /B 1 

:END 
+0

scheint nicht zu funktionieren: C: \> test.bat C: \> del boo.doc boo.doc. Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird. C: \> wenn errorlevel 1 zu FAIL C: \> echo funktioniert! Arbeitete! C: \> Echo fehlgeschlagen! Fehlgeschlagen! C: \> exit/B 1 –

6

DEL keine Errorlevel zurück, wenn die Datei gesperrt ist. Ich habe gerade einen Test mit Excel-Datei gemacht und ich sah eine Null (unter Windows XP).

Es ist möglicherweise besser, IF EXIST für die Datei zu verwenden, die nach dem Löschen gelöscht werden soll.

del file.txt 
if exist file.txt ECHO "FAIL" 

NACH EDIT Haftungsausschluss: Ich habe keine Ahnung, wie diese führt ...

Sie können dies tun, für die Dateien

DIR /B /S /A-d > c:\filestodelete.txt 

del *.* /S /Q  

FOR /F %%i in (c:\filestodelete.txt) DO (
    IF EXIST %%i ECHO %%i STILL EXISTS 
) 

dann für die Verzeichnisse

DIR /B /S /Ad > c:\directoriestodelete.txt 

FOR /D %%G in (*) DO RD /s /q %%G  

FOR /F %%i in (c:\directoriestodelete.txt) DO (
    IF EXIST %%i ECHO %%i STILL EXISTS 
) 
+0

Guter Vorschlag - außer ich entferne mehrere Dateien (siehe bearbeitet Post), so ist es schwer, die Existenz-Anweisung für jedes Verzeichnis/Datei zu tun. –

+0

@Marcus Leon - Ich denke, was ich hinzugefügt habe sollte für Ihren allgemeinen Fall funktionieren ... –

1

Hier ist meine bevorzugte Methode zum Überprüfen auf Fehler beim Löschen von Dateien. Wir leiten die „Fehlerausgabe“ (Standard-Datei „2“) in eine Datei (z.B. delCmd.err). Dann verwenden wir den FOR-Befehl, um Zugriff auf den Operanden "z-Dateigröße" zu erhalten. Wenn die Größe der Ausgabedatei nicht gleich 0 ist, dann, dass wir wissen, „del“ einen Fehler bekam ... wir zeigen den Fehler mit dem „Typ“ Befehl und beenden Sie die Batch-Datei mit einem Nicht-Null-Fehler-Code:

del unwanted.txt 2> delCmd.err 
FOR /F "usebackq" %%A IN ('delCmd.err') DO set size=%%~zA 
if not "%size%"=="0" (
    echo Error deleting unwanted.txt 
    type delCmd.err 
    exit /B 1 
) 
+0

+1, Doh! So einfach! – dbenham

1

Hier ist eine kürzere Version der Ergebnis Überwachung Variante.Dies verwendet 2>&1 Trick um stderr auf stdout umzuleiten und for /f, um auf jeden Ausgang zu überprüfen.

@echo off 
setlocal 
set error=0 
for /f %%i in ('del notepad2.exe 2^>^&1') do set error=1 
echo %error% 
0

Es gibt ein Skript, das wie ein Zauber funktioniert. Es testet Löschungsfehler durch Testen der Existenz der vermeintlich gelöschten Datei/des Verzeichnisses.

Die Ausgabe wird ein vorhandenes c: \ mydirectory mit vollständig leerem Inhalt sein. Jeder Fehler unterbricht den Prozess und wird gemeldet.

Der einzige Nachteil ist, dass Verzeichnisse rekursiv entfernt werden, da es keine einfache Möglichkeit gibt, Verzeichnisse zu löschen, die mit den meisten "Unterverzeichnissen" beginnen.

@echo OFF 
set path_to_clean=c:\mydirectory 

@echo -Deleting Files 
dir /A-D /S /B %path_to_clean%\* > fileslist.txt 
for /F %%F in (fileslist.txt) do (
    @echo Deleting %%F 
    del %%F 2> nul 
    if exist %%F (
     @echo Cannot delete %%F, it is locked. 
     goto errorhandling 
    ) 
) 
del fileslist.txt 
@echo -Deleting Files done 

@echo -Deleting Directories 
dir /AD /B %path_to_clean%\* > directorieslist.txt 

for /F %%D in (directorieslist.txt) do (
    @echo Deleting %path_to_clean%\%%D 
    rmdir /S /Q %path_to_clean%\%%D 2> nul 
    if exist %path_to_clean%\%%D (
     @echo Cannot delete %path_to_clean%\%%D. This folder or one of its sub-directories is locked. 
     goto errorhandling 
    ) 
) 
del directorieslist.txt 
@echo -Deleting Directories done 

:errorhandling 
rem some code here 
-1

Für rd und rmdir können Sie

rd "some directory" || rem 

tun dies die Error-richtig eingestellt - see

+0

Leider funktioniert dieser Trick nicht mit dem DEL-Befehl :-( – dbenham

+1

auch rd setzt Errorlevel nicht für alle Fehlerbedingungen (zB für Zugriff verweigert) – jhyot

-2

Hallo Dies sollte auch funktionieren

@echo off 

for /f %%i in ('del notepad2.exe 2^>^&1') do set ERRORLEVEL=1 
IF %ERRORLEVEL%=1 then exit 
+3

Sie sollten *** NIE *** die ERRORLEVEL-Variable direkt setzen. Der Benutzer definiert value überschreibt den dynamischen Wert. '% ERRORLEVEL%' meldet den zurückgegebenen Fehlercode des vorherigen Befehls nicht mehr, stattdessen wird er für immer auf den von Ihnen festgelegten Wert erweitert. – dbenham

0

Diese scheinen zu arbeiten für mich:

RD:

FOR /D %d IN (*) DO (RD /S /Q "%d" & IF EXIST "%d" EXIT /B 1) 

DEL: obwohl

FOR %f IN (*.*) DO (DEL /Q "%f" & IF EXIST "%f" EXIT /B 1) 

Keine Ahnung über die Leistung.

Sie können Flag/F für einen "erzwungenes Löschen" -Modus zu DEL hinzufügen.

1

Nur zu Ihrer Information. Der DEL-Befehl gibt einen Fehlercode zurück, wenn ein schwerwiegender Fehler auftritt, jedoch ist das Verhalten weit jenseits unserer Intuition, dass die Leute einfach glauben würden, dass der Fehlercode überhaupt nicht funktioniert.

Das ist, was ich in DEL-Befehl in Windows 7 getestet haben:

  • Erfolgreiche Löschung aller Dateien: 0 (natürlich)
  • Manche Dateien gelöscht, fehlen einige Dateien: 0 (Intuition erwartet 1)
  • Löschversagen aufgrund ohne Erlaubnis oder ein nur-Lese-Medium: 0 (Intuition ≥ 1)
  • nicht vorhandenes Laufwerk erwartet oder nicht Laufwerk bereit (wie keine CD auf einem CD-ROM-Laufwerk): 1 (ja, Sie bekommen es, aber ich werde einen höheren Fehlercode erwarten)
  • ungültiger Pfad: 1 (Ich werde einen höheren Fehlercodes erwartet auch)

Und wenn Sie eine Liste von Dateien zu DEL-Befehl angeben, wobei mindestens eine der Dateien, die letzten passen zwei Arten von Fehler oben erwähnt, dann keine der Dateien in der Liste wird überhaupt gelöscht werden.