In a DOS batch file you are supposed to be able to do this:
setlocal enabledelayedexpansion
... and then any variables that fall inside IF statements or FOR loops in the batch file are supposed to evaluate more like a real computer program instead of being the same value throughout the local scope of the IF or FOR.
All the docs I see on the web (such as
https://ss64.com/nt/delayedexpansion.html ) say that I can optionally use either exclamation marks or percent signs to surround the variable name that I want to evaluate with delayed expansion.
None of them say that I *must* use exclamation marks on the delayed-expansion variables.
But in my tests it indeed looks like I must use the exclamation marks.
When I run the test below, the results from the percent-sign version of the test gets incorrect results, as if I had not done "setlocal enabledelayedexpansion", whereas the exclamation-mark version works as expected.
file: testExitError.cmd
@echo off
:: Turn on delayed expansion, the behavior of which is the thing we want to test here today.
setlocal enabledelayedexpansion
:: Create sub-file for the test cases to call.
set subFileName=testExitErrorSubFile.cmd
echo @echo off > "%~dp0%subFileName%"
echo echo Testing delayed expansion, testing %%2 expecting %%1 >> "%~dp0%subFileName%"
echo exit /B %%2 >> "%~dp0%subFileName%"
:: Call all the test cases and get the output.
:: --------------------------------------------------------
:: expected result value to test
:: --------------------------------------------------------
call :TestExitError zero 0
call :TestExitError nonzero 1
call :TestExitError zero 0
call :TestExitError nonzero 2
call :TestExitError zero 0
call :TestExitError nonzero -1
call :TestExitError zero 0
call :TestExitError nonzero -2
call :TestExitError zero 0
call :TestExitError nonzero 65535
call :TestExitError zero 0
call :TestExitError nonzero -532462766
call :TestExitError zero 0
:: End of program
pause
goto:eof
:: The workhorse test subroutine
:TestExitError
:: To test this properly, I must nest the actual test inside an IF statement
:: so that the delayed expansion can make a difference. Without this outer
:: IF statement, it doesn't matter if I use delayed expansion or not.
IF "Hello"=="Hello" (
call "%~dp0%subFileName%" %1 %2
IF !ERRORLEVEL! NEQ 0 (
echo Result with exclamations: testing %2 result is nonzero
) ELSE (
echo Result with exclamations: testing %2 result is zero
)
call "%~dp0%subFileName%" %1 %2
IF %ERRORLEVEL% NEQ 0 (
echo Result with percent signs: testing %2 result is nonzero
) ELSE (
echo Result with percent signs: testing %2 result is zero
)
)
echo:
goto:eof
Anyone know why?