2012-06-21 10 views
11

Ich schreibe ein Batch (.bat) Skript und ich muss den Fall behandeln, in dem das Löschen eines Ordners fehlschlägt. Ich verwende %errorlevel% den Exit-Code zu fangen, aber im Fall des rd Befehls nicht zu funktionieren scheint:Batch: Exit-Code für "rd" ist 0 bei Fehler

C:\Users\edo\Desktop>rd testdir 
Directory is not empty 

C:\Users\edo\Desktop>echo %errorlevel% 
0 

Warum? Was schlagen Sie vor?
Danke!

Antwort

20

Wow, das ist der zweite Fall, in dem ich gesehen habe, wo ERRORLEVEL nicht richtig eingestellt ist! Siehe File redirection in Windows and %errorlevel%.

Die Lösung ist die gleiche wie beim Erkennen eines Umleitungsfehlers. Verwenden Sie den Operator ||, um bei einem Fehler Maßnahmen zu ergreifen.

rd testdir || echo The command failed! 

Die bizarre Sache ist, wenn Sie den || Operator verwenden, die Error-dann richtig auf 145 gesetzt, wenn der Ordner nicht leer war, oder 2, wenn der Ordner nicht existiert. Du musst also gar nichts machen. Sie können eine Bemerkung bedingt "ausführen", und der errorlevel wird dann richtig gesetzt.

rd testdir || rem 
echo %errorlevel% 

aktualisiert 2016.01.21

Bereits im April 2015, behauptete Andreas Vergison in einem Kommentar, dass || nicht die Error-für "Zugriff verweigert" gesetzt hat, oder“... In Verwenden Sie ... "Fehler. Ich hatte Windows 7 zu der Zeit, und ich glaube nicht, dass ich seinen Anspruch verifiziert habe, sondern nur angenommen habe, dass er Recht hatte. Aber ich habe kürzlich in Windows 10 getestet, und die || setzt immer das ERRORLEVEL bei Fehler auf Null. Beachten Sie, dass (call) eine arkane Art ist, das ERRORLEVEL auf 0 zu setzen, bevor ich jeden Befehl ausführe. Beachten Sie auch, dass meine cmd.exe-Sitzung die verzögerte Erweiterung aktiviert hat.

C:\test>(call) & rd junk && echo OK || echo ERROR !errorlevel! 
Access is denied. 
ERROR 5 

C:\test>(call) & rd test && echo OK || echo ERROR !errorlevel! 
The directory is not empty. 
ERROR 145 

C:\test>(call) & rd \test && echo OK || echo ERROR !errorlevel! 
The process cannot access the file because it is being used by another process. 
ERROR 32 

C:\test>(call) & rd notExists && echo OK || echo ERROR !errorlevel! 
The system cannot find the file specified. 
ERROR 2 
+0

Nun, das hat gerade funktioniert. Ich nehme an, das Problem hängt mit '% errorlevel%' zusammen und hat nichts mit 'rd' zu tun. Ich denke, ich sollte meine Fehlerbehandlungen neu schreiben, indem ich diese Struktur für ein deterministischeres Verhalten verwende. Vielen Dank! – etuardu

+3

Dies funktioniert gut für die Codes 2 und 145, aber im Falle von "Zugriff verweigert" oder "Der Prozess kann nicht auf die Datei zugreifen, weil es von einem anderen Prozess verwendet wird", bleibt ERRORLEVEL unverändert. :( –

+0

@AndreasVergison - Danke! Ich aktualisierte meine Antwort mit Ihrer Info. – dbenham

3

rd setzt keine errorlevel auf Null - es lässt errorlevel intakt: F. E. Wenn der vorherige Vorgang mit errorlevel endet und rd erfolgreich beendet wird, wird errorlevel unverändert beibehalten. Beispiel: Fehlerebene von robocopy unter 4 sind Warnungen und Fehler nicht und können ignoriert werden, so dass der folgende Code mit Fehlern enden kann, selbst wenn das Verzeichnis erfolgreich gelöscht wurde:

robocopy ... 
if errorlevel 4 goto :error 
rd somedir 
if errorlevel 1 goto :error 

Lösung: die Fehler ignorieren und prüfen Sie, ob das Verzeichnis existiert noch nach rd:

rd somedir 
if exist somedir goto :error 
+1

Auch über 'robocopy': sei sicher ** nicht ** um den errorlevel mit' set errorlevel = 0' zurückzusetzen, nachdem du es nicht> = 4 überprüft hast, da dieser Befehl eine Umgebungsvariable erstellt, die das interne permanent überschreibt Fehlerlevel. Lesen Sie [hier] (http://blogs.msdn.com/b/oldnewthing/archive/2008/09/26/8965755.aspx) – rychu

Verwandte Themen