I have a weird behavior wrt setting errorlevel in a batch script to 0.
I am calling a batch script a.bat
on a Jenkins job, which in turn calls a second script b.cmd
and evaluates the errorlevel after the call:
:: b.cmd
:: some stuff, but relevant is only this:
@echo b errorlevel: %errorlevel%
EXIT /B 0
The "main" script:
:: a.bat
pushd %CD%
cd..
@echo a errorlevel: %errorlevel%
set outputdir=".\some\exisiting\dir"
:: (1)
md %outpurdir%
@echo a errorlevel: %errorlevel%
:: (!)
if "$somevar" = "FOO" (
cd .\WhereBIs
:: (2)
call :seterr 0
@echo a errorlevel: %errorlevel%
:: (3)
call b.cmd
@if %errorlevel% neq 0 (
@echo a errorlevel: %errorlevel%
set errmsg=Error calling b
goto error
)
:: more stuff
)
:error
@echo %errmsg%
popd
:: (4)
@echo a errorlevel: %errorlevel%
@if %errorlevel% neq 0 exit %errorlevel%
Exit /B 1
:seterr
exit /b %1
(I borrowed the :seterr
stuff from this question)
What seems to happen when I run the Jenkins job:
md
returns and errorlevel is set to 1, because the directory already exists.- the call to
:seterr
does not have the expected effect, errorlevel remains 1 - the call to
b.cmd
completes without problems, errorlevel inb
is 0, but after the call errorlevel ina
is still 1, which I would definitely not expect after reading the answers to the linked question. - after the jump to
:error
and call ofpopd
, errorlevel is suddenly reset to 0 – which I would not expect either.
Does anybody have a clue what might be happening here? I did not accidentally set errorlevel manually, so it should be the system variable, not a userdefined one.
Best Answer
You have not shown the entire script. The only possible explanation I am aware of is your code is within a larger parenthesized block of code, possibly part of a FOR loop or an IF condition.
%ERRORLEVEL% is expanded when the line is parsed, and the entire parenthesized block is parsed at the same time. So the ERRORLEVEL that you are seeing must have existed prior to the start of the outermost paranthesis.
You should use delayed expansion if you want to see a changing value within a code block.
Here is a simple demonstration:
-- OUTPUT --