IF,CALL,EXIT和%ERRORLEVEL%.bat

任何人都可以请帮我理解%ERRORLEVEL%variables的行为,以及为什么它没有设置一个CALL ,而是在一个IF ,即ECHO %ERRORLEVEL%.2行吗?

 @ECHO OFF SET ERRORLEVEL VERIFY > NUL ECHO %ERRORLEVEL%.0 IF ERRORLEVEL 1 ECHO SNAFU IF %ERRORLEVEL% == 0 ( ECHO %ERRORLEVEL%.1 CALL :FOO ECHO %ERRORLEVEL%.2 IF ERRORLEVEL 42 ECHO 42.3 ) GOTO :EOF :FOO EXIT /B 42 GOTO :EOF 

STDOUT

 C:\Users\Ilya.Kozhevnikov\Dropbox>foo.bat Environment variable ERRORLEVEL not defined 0.0 0.1 0.2 42.3 

但是,如果没有IF %ERRORLEVEL%variables设置为预期。

 @ECHO OFF SET ERRORLEVEL VERIFY > NUL ECHO %ERRORLEVEL%.0 IF ERRORLEVEL 1 ECHO SNAFU REM IF %ERRORLEVEL% == 0 ( ECHO %ERRORLEVEL%.1 CALL :FOO ECHO %ERRORLEVEL%.2 IF ERRORLEVEL 42 ECHO 42.3 REM ) GOTO :EOF :FOO EXIT /B 42 GOTO :EOF 

STDOUT

 C:\Users\Ilya.Kozhevnikov\Dropbox>foo.bat Environment variable ERRORLEVEL not defined 0.0 0.1 42.2 42.3 

当cmd解析器读取一行或一行代码块(括号内的代码)时, 开始执行代码之前 ,所有变量读取都将用变量内的值替换。 如果块中代码的执行更改了变量的值,则该值不能在同一个块内部看到,因为变量的读取操作不存在,所以将其替换为变量中的值

为了解决这个问题,你需要启用延迟扩展,并根据需要将语法从%var%更改为!var! ,向解析器指示读操作需要被延迟直到执行命令。

 @ECHO OFF setlocal enabledelayedexpansion SET ERRORLEVEL VERIFY > NUL ECHO %ERRORLEVEL%.0 IF ERRORLEVEL 1 ECHO SNAFU IF %ERRORLEVEL% == 0 ( ECHO !ERRORLEVEL!.1 CALL :FOO ECHO !ERRORLEVEL!.2 IF ERRORLEVEL 42 ECHO 42.3 ) GOTO :EOF :FOO EXIT /B 42 GOTO :EOF 

MC ND已经很好的回答了这个问题。

下面是一个替代代码,显示了ERRORLEVEL的扩展和延迟扩展。

 @ECHO OFF SETLOCAL ENABLEDELAYEDEXPANSION VERIFY > NUL ECHO !ERRORLEVEL!.0 delayed ECHO %ERRORLEVEL%.0 expanded IF ERRORLEVEL 1 ECHO SNAFU IF !ERRORLEVEL! == 0 ( ECHO !ERRORLEVEL!.1 delayed ECHO %ERRORLEVEL%.1 expanded CALL :FOO ECHO !ERRORLEVEL!.2 delayed ECHO %ERRORLEVEL%.2 expanded ) ENDLOCAL GOTO :EOF :FOO EXIT /B 42 GOTO :EOF 

微软在命令set帮助下描述了延迟扩展的行为,可以在进入set /?命令后在命令提示符窗口中读取这些行为set /?help set