ERRORLEVEL-Umgebungsvariable wird im Batch-Skript aktualisiert,% ERRORLEVEL% jedoch nicht

871
user3377627

Ich habe das folgende Batch-Skript, das auf einem FTP-Server ausgeführt wird. Ich verwende einen Scheduler, der 4 Variablen übergibt. SouRce, EXTension, DESTination und ZIP-Verzeichnis. Es ist ein einfaches Skript, das die ersten drei Variablen erfordert. Der Benutzer kann jedoch die letzte vierte auslassen, wenn die Dateien nicht gezippt werden müssen.

@ECHO OFF  SET SRC=%1 SET EXT=%2 SET DEST=%3 SET ZIPD=%4 SET DTE=%DATE:~4,2%%DATE:~7,2%%DATE:~10,4% FOR /F "TOKENS=1-3 DELIMS=: " %%L IN ('TIME /T') DO SET hhmm=%%L%%M%  DIR /B /A:-d %SRC% IF ERRORLEVEL 1 ( ECHO *** There are no files to process. *** RC=%ERRORLEVEL% SET ERRORLEVEL=0 GOTO EXIT )  DEL /Q %SRC%\Thumbs.db  IF DEFINED ZIPD ( WZZIP %ZIPD%\%DTE%%hhmm%.zip %SRC%\*%EXT% IF ERRORLEVEL 1 ( ECHO *** WZZIP for "%SRC%\*%EXT%" failed. *** RC=%ERRORLEVEL% ECHO. GOTO EXIT ) ECHO. ECHO successfully zipped %SRC% TO %ZIPD%: %DTE%%hhmm%.zip ECHO. )  MOVE /Y %SRC%\*%EXT% %DEST% IF ERRORLEVEL 1 ( ECHO ** MOVE "%SRC%\*%EXT%" TO "%DEST%" Failed. *** RC=%ERRORLEVEL% )  :EXIT EXIT /B %ERRORLEVEL% 

Das Problem, dem ich begegne, ist, dass, wenn sich um 08:15 Uhr nichts im Verzeichnis befindet (Scheduler führt es aus),

DIR /B /A:-d %SRC% 

schlägt mit einem Errorlevel von 1 fehl. Er geht in die Schleife und wird beendet. Der Test für den Errorlevel funktioniert sowohl als

IF ERRORLEVEL 1 

und wie

IF NOT %ERRORLEVEL% == 0 

Ich stoße auf das Problem, dass nachfolgende Fehler die Benutzervariable% ERRORLEVEL% nicht aktualisieren. Deshalb MUSS ICH IF ERRORLEVEL 1 für die anderen Prüfungen verwenden. Wenn WZZIP jetzt fehlschlägt, geht es in die Schleife nach dem Befehl, aber die ECHO-Nachricht spuckt "RC = 0" aus, obwohl ERRORLEVEL größer als oder gleich 1 sein musste und daher% ERRORLEVEL% auf aktualisiert haben sollte was auch immer es sein soll. Ich habe das Hinzufügen des Skripts getestet

ECHO %ERRORLEVEL% 

zu jeder anderen Zeile, nur um die Änderungen zu sehen, und obwohl der DIR-Test% ERRORLEVEL% korrekt aktualisiert, wird erneut DEL der thumb.db, die zu 99,999% der Zeit fehlschlägt,% ERRORLEVEL% = 0 und WZZIP zurückgegeben, wenn sie zum Scheitern gezwungen sind kommt auch aus RC = 0. Versuchte SETLOCAL, SETLOCAL ENABLEEXTENSIONS und ein paar andere Sachen. Es wurde sogar versucht, alles außer dem WZZIP-Teil zu entfernen. Trotzdem werden% ERRORLEVEL% nicht aktualisiert. Es ist ein FTP-Server, auf dem wir ständig Skripts zum Übertragen von Dateien ausführen. Ich habe mich gefragt, ob es möglicherweise Konflikte mit anderen cmd-Streams gibt, die die env-Variable ändern, während ich mein Skript ausführte. Darüber hinaus wurden die meisten anderen Skripts nicht von mir geschrieben und sie lieben es, SET ERRORLEVEL=whatevernumberund ich weiß, dass dies Konflikte in der Vergangenheit verursacht hat. Ich frage mich, ob dies der Täter sein könnte.

2
Lesen Sie [Verzögerte Erweiterung] (http://ss64.com/nt/delayedexpansion.html), google _ "verzögerte Erweiterungsfalle" _ für Beispiele. JosefZ vor 8 Jahren 0

1 Antwort auf die Frage

1
JosefZ

Sie benötigen eine verzögerte Erweiterung, wenn Sie eine Variable verwenden möchten, die Sie in demselben Befehlsblock geändert haben. (Ein Befehlsblock besteht aus einer Reihe von Befehlen in Klammern (und ).) Verzögerte Variablen werden mit !var!anstelle von verwendet %var%.

Beispiel :

@ECHO OFF SETLOCAL EnableExtensions EnableDelayedExpansion cmd /C exit /B 99 echo before ^(command block^) %%errorlevel%%=%errorlevel% ^^!errorlevel^^!=!errorlevel! ( (call) echo ^(inside command block^) %%errorlevel%%=%errorlevel% ^^!errorlevel^^!=!errorlevel! (call ) echo ^(inside command block^) %%errorlevel%%=%errorlevel% ^^!errorlevel^^!=!errorlevel! ) echo after ^(command block^) %%errorlevel%%=%errorlevel% ^^!errorlevel^^!=!errorlevel! 

Ausgabe :

==> D:\bat\SU\1113027.bat before (command block) %errorlevel%=99 !errorlevel!=99 (inside command block) %errorlevel%=99 !errorlevel!=1 (inside command block) %errorlevel%=99 !errorlevel!=0 after (command block) %errorlevel%=0 !errorlevel!=0 

Die (call)und (call )Tricks, die dieser Dbenham-Antwort auf die Einstellung von ERRORLEVEL auf 0 gestohlen wurde :

Wenn Sie die erzwingen wollen errorlevelzu 0, dann können Sie diese völlig nicht-intuitive, verwenden aber sehr effektiv Syntax: (call ). Der Platz nach dem Anruf ist kritisch. Wenn Sie die einstellen wollen, errorlevelum 1, können Sie verwenden (call). Es ist wichtig, dass nach dem Aufruf kein Platz vorhanden ist.