任何人都可以请帮我理解%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