It seems that since I use SET to declare my variables in batch script, if I run it multiple times in cmd, the variable value will persist unless I explicitly reset them.
Do I have to use setlocal and endlocal to make sure the variables from one run doesn't persist over to another, without shutting down the CMD?
Yes, you should use SETLOCAL. That will localize any changes such that the old environment will be restored once ENDLOCAL is issued.
When all script processing finishes and you are returned to a command line context, there is an implicit ENDLOCAL issued for every active SETLOCAL. There is no need to explicitly issue ENDLOCAL.
Also, if your script (or routine) is CALLed, then when the CALL completes there is an implicit ENDLOCAL for every active SETLOCAL that was issued within the CALLed routine. No need to put ENDLOCAL at end of a routine, (though it doesn't hurt)
For example
@echo off
set var=pre-CALL value
echo var=%var%
call :test
echo var=%var%
exit /b
:test
setlocal
set var=within CALL value
echo var=%var%
exit /b
output:
var=pre-CALL value
var=within CALL value
var=pre-CALL value
ENDLOCAL within a CALLed routine will never rollback a SETLOCAL that was issued before the CALL. For example.
@echo off
setlocal
set var=VALUE 1
setlocal
set var=VALUE 2
echo before call: var=%var%
call :test
echo after call: var=%var%
endlocal
echo after endlocal: var=%var%
exit /b
:test
setlocal
set var=VALUE 3
echo within local CALL context: var=%var%
endlocal
echo within CALL after 1st endlocal: var=%var%
endlocal
echo within CALL cannot endlocal to before CALL state: var=%var%
exit /b
Result:
before call: var=VALUE 2
within local CALL context: var=VALUE 3
within CALL after 1st endlocal: var=VALUE 2
within CALL cannot endlocal to before CALL state: var=VALUE 2
after call: var=VALUE 2
after endlocal: var=VALUE 1