.bat中的IF,CALL,EXIT和%ERRORLEVEL%

Ily*_*kov 6 windows batch-file

任何人都可以帮助我理解%ERRORLEVEL%变量的行为以及为什么它在一段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
Run Code Online (Sandbox Code Playgroud)

STDOUT

C:\Users\Ilya.Kozhevnikov\Dropbox>foo.bat
Environment variable ERRORLEVEL not defined
0.0
0.1
0.2
42.3
Run Code Online (Sandbox Code Playgroud)

然而,如果没有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 :EOF
Run Code Online (Sandbox Code Playgroud)

STDOUT

C:\Users\Ilya.Kozhevnikov\Dropbox>foo.bat
Environment variable ERRORLEVEL not defined
0.0
0.1
42.2
42.3
Run Code Online (Sandbox Code Playgroud)

MC *_* ND 8

当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
Run Code Online (Sandbox Code Playgroud)