谁能帮我理解一下%ERRORLEVEL%变量的行为,以及为什么在IF (即IF行)中没有在CALL之后设置它?
@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 :EOFSTDOUT
C:\Users\Ilya.Kozhevnikov\Dropbox>foo.bat
Environment variable ERRORLEVEL not defined
0.0
0.1
0.2
42.3但是,如果没有IF,则按预期设置%ERRORLEVEL%变量。
@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 :EOFSTDOUT
C:\Users\Ilya.Kozhevnikov\Dropbox>foo.bat
Environment variable ERRORLEVEL not defined
0.0
0.1
42.2
42.3发布于 2014-07-21 13:47:45
当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发布于 2014-07-21 13:57:35
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 :EOFMicrosoft描述了在命令set的帮助下延迟展开的行为,在输入set /?或help set后,可以在命令提示符窗口中读取该命令。
https://stackoverflow.com/questions/24866477
复制相似问题