ERRORLEVEL 环境变量在批处理脚本中更新,但 %ERRORLEVEL% 没有更新

ERRORLEVEL 环境变量在批处理脚本中更新,但 %ERRORLEVEL% 没有更新

我有以下在 ftp 服务器上运行的批处理脚本。我使用传递 4 个变量的调度程序:SouRCe、EXTension、DESTination 和 ZIP Directory。这是一个简单的脚本,需要前 3 个变量,但如果用户不需要压缩文件,则可以省略最后第 4 个变量。

@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%

我遇到的问题是,如果上午 8:15 时目录中没有任何内容(调度程序运行它),

DIR /B /A:-d %SRC%

失败,错误级别为 1。它进入循环并退出。错误级别的测试既可以作为

IF ERRORLEVEL 1

并作为

IF NOT %ERRORLEVEL% == 0

我遇到的问题是,任何后续失败都不会更新 %ERRORLEVEL% 的用户变量。这就是为什么我必须使用 IF ERRORLEVEL 1 进行其他检查的原因。现在,如果 WZZIP 失败,它会进入命令后的循环,但 ECHO 消息会吐出“RC=0”,即使 ERRORLEVEL 必须大于或等于 1,因此应该将 %ERRORLEVEL% 更新为它应该有的值。我测试了脚本,添加了

ECHO %ERRORLEVEL%

每隔一行查看变化,即使 DIR 测试正确更新了 %ERRORLEVEL%,再次 DEL 删除 thumb.db(99.999% 的时间都会失败),结果还是 %ERRORLEVEL% = 0,而 WZZIP 如果被迫失败,结果也是 RC=0。试过 SETLOCAL、SETLOCAL ENABLEEXTENSIONS 和其他一些东西,甚至尝试删除 WZZIP 部分以外的所有内容,但仍然没有更新 %ERRORLEVEL%。这是一个 FTP 服务器,我们不断运行脚本来传输文件,所以我想知道在我运行脚本时,其他 cmd 流是否会更改环境变量,从而产生冲突?此外,大多数其他脚本不是我编写的,他们很喜欢使用SET ERRORLEVEL=whatevernumber,我知道这在过去给我带来过冲突。我想知道这是否是罪魁祸首。

答案1

你需要延迟扩张如果您想使用变量,请在同一个命令块中更改该变量。(A命令块(是括号和内的一系列命令)。)延迟变量使用!var!而不是来引用%var%

例子

@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!

输出

==> 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

(call)技巧(call )窃取自这是 Dbenham 的回答将 ERRORLEVEL 设置为 0问题:

如果你想errorlevel强制 0,那么您可以使用这个完全非直观但非常有效的语法: (call )。call 后面的空格非常重要。如果errorlevel要将 1, 您可以使用 (call). 至关重要的是,call 之后不能有任何空格。

相关内容