.bat中的IF,CALL,EXIT和%ERRORLEVEL% [英] IF, CALL, EXIT and %ERRORLEVEL% in a .bat

查看:483
本文介绍了.bat中的IF,CALL,EXIT和%ERRORLEVEL%的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以帮助我理解%ERRORLEVEL%变量的行为以及为什么在IF内(即 ECHO %ERRORLEVEL%.2 行)中没有在CALL之后设置它的原因吗?/p>

@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%变量将按预期设置.

@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

Can anyone please help me understand the behaviour of %ERRORLEVEL% variable and why it's not being set after a CALL while being inside an IF, i.e. the ECHO %ERRORLEVEL%.2 line?

@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

However, without IF the %ERRORLEVEL% variable is set as expected.

@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

解决方案

When the cmd parser reads a line or a block of lines (the code inside the parenthesis), all variable reads are replaced with the value inside the variable before starting to execute the code. If the execution of the code in the block changes the value of the variable, this value can not be seen from inside the same block, as the read operation on the variable does not exist, it was replaced with the value in the variable

To solve it, you need to enable delayed expansion, and, where needed, change the syntax from %var% to !var!, indicating to the parser that the read operation needs to be delayed until the execution of the command.

@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

这篇关于.bat中的IF,CALL,EXIT和%ERRORLEVEL%的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆