can explain me why following snippet prints 0
:
@echo off setlocal /f %%i in ('cmd /c echo blah') ( echo %%i | findstr bin > nul echo %errorlevel% )
while adding another, equivalent statement outside of for-loop makes print 1 1
:
@echo off setlocal echo blah | findstr bin > nul echo %errorlevel% /f %%i in ('cmd /c echo blah') ( echo %%i | findstr bin > nul echo %errorlevel% )
i'm bit of newbie batch, kinda mysterious me since 2 statements seem unrelated. appreciated, thanks!
the issue within code block
(parenthesised series of statements) %var%
will replaced actual value of variable @ parse time
.
hin first example, %errorlevel%
0
, echoed such. in second example, 1
when for
encountered, hence it replaced 1
.
if want display value of environment variable may changed within loop, need 1 of 3 things:
invoke
setlocal enabledelayedexpansion
, echo!var!
instead of%var%
- noting number of nestedsetlocal
instructions can have active limited.call subroutine
employ syntax-exploit.
there many, many articles delayedexpansion
on so.
crudely, use (note - case largely irrelevant in batch, except case of loop-control variable (metavariable
- %%i
in instance)
@echo off setlocal enabledelayedexpansion echo blah | findstr bin > nul echo %errorlevel% or !errorlevel! /f %%i in ('cmd /c echo blah') ( echo %%i | findstr bin > nul echo %errorlevel% or !errorlevel! )
another way dynamically invoke setlocal
@echo off setlocal echo blah | findstr bin > nul echo %errorlevel% or !errorlevel! /f %%i in ('cmd /c echo blah') ( echo %%i | findstr bin > nul setlocal enabledelayedexpansion echo %errorlevel% or !errorlevel! endlocal )
the disadvantage of endlocal
backs out changes made environment since last setlocal
. note if delayedexpansion
not in effect, !
no longer special character.
or, can use errorlevel
in traditional manner:
@echo off setlocal echo blah | findstr bin > nul echo %errorlevel% or !errorlevel! /f %%i in ('cmd /c echo blah') ( echo %%i | findstr bin > nul if errorlevel 1 (echo errorlevel 1 or greater ) else (echo errorlevel 0 ) )
note looks @ run-time
value of errorlevel
, if errorlevel n
means "if errorlevel n or greater n"
or - call subroutine:
@echo off setlocal echo blah | findstr bin > nul echo %errorlevel% or !errorlevel! /f %%i in ('cmd /c echo blah') ( echo %%i | findstr bin > nul call :show ) goto :eof :show echo %errorlevel% goto :eof
note here goto :eof
(here colon important - means "go physical end-of-file"
or, special version of using subroutine - syntax-exploit
@echo off setlocal echo blah | findstr bin > nul echo %errorlevel% or !errorlevel! /f %%i in ('cmd /c echo blah') ( echo %%i | findstr bin > nul call echo %%errorlevel%% )
Comments
Post a Comment