Page 1 of 1

Scope termination and echo state

Posted: 06 Aug 2024 16:34
by mataha
I've encountered a behaviour I do not quite understand.

Code: Select all

C:\Users\user> A.cmd

Waiting for 1 seconds, press a key to continue ...

A.cmd:

Code: Select all

@echo off
(goto) 2>nul || B.cmd
B.cmd

Code: Select all

@echo off
(goto) 2>nul || "%SystemRoot%\system32\timeout.exe" /t 1
Why is echo state not restored afterwards? Does using (goto) in order to run other scripts make any sense? Should I just run them directly, then?

Re: Scope termination and echo state

Posted: 07 Aug 2024 08:34
by jeb
Hi mataha,

I don't understand why you use the "(goto) 2>nul" at all.
And starting another batch file without CALL ?

The (goto) construct can be used as a special EXIT with quite different behavior.

(goto) works like EXIT /B, it pops the program stack and rolls back all SETLOCAL to the old state when last pushing on the program stack.
But in spite of an EXIT/B or a successful GOTO, it doesn't cancel the current code block.

This can be used for many interesting hacks, like stackdumps/errorhandling, ...
I'll show the difference, by changing the first (GOTO) to an EXIT/B in the second example

myBatch1.bat

Code: Select all

@echo off
setlocal EnableDelayedExpansion
set var=0
(
call echo #Main:1 var=!var! "%%0"
call :func
call echo #Main:6 var=!var! Back in Main "%%0"
)
echo #Main:9 THIS LINE WILL NEVER BE REACHED
exit /b

:func
setlocal
set /a var+=1
setlocal
set /a var+=1
setlocal
set /a var+=1
(
  call echo #Func:2 var=!var! "%%0"
  endlocal
  call echo #Func:3 var=!var! "%%0"
  (goto) 2> nul
  call echo #Func:4 var=!var! "%%0"
  (goto) 2> nul
  call echo #Func:5 var=!var! "%%0"
)
echo #func:6 THIS LINE WILL NEVER BE REACHED
#Main:1 var=0 "myBatch1.bat"
#Func:2 var=3 ":func"
#Func:3 var=2 ":func"
#Func:4 var=0 "myBatch1.bat"
#Func:5 var=!var! "%0"
#Main:6 var=!var! Back in Main "%0"


myBatch1.bat

Code: Select all

@echo off
setlocal EnableDelayedExpansion
set var=0
(
call echo #Main:1 var=!var! "%%0"
call :func
call echo #Main:6 var=!var! Back in Main "%%0"
)
echo #Main:9 THIS LINE WILL NEVER BE REACHED
exit /b

:func
setlocal
set /a var+=1
setlocal
set /a var+=1
setlocal
set /a var+=1
(
  call echo #Func:2 var=!var! "%%0"
  endlocal
  call echo #Func:3 var=!var! "%%0"
  EXIT /B
  call echo #Func:4 var=!var! "%%0"
  (goto) 2> nul
  call echo #Func:5 var=!var! "%%0"
)
echo #func:6 THIS LINE WILL NEVER BE REACHED
#Main:1 var=0 "myBatch2.bat"
#Func:2 var=3 ":func"
#Func:3 var=2 ":func"
#Main:6 var=0 Back in Main "myBatch2.bat"
#Main:9 THIS LINE WILL NEVER BE REACHED
(goto) allows some more control over the program flow.

But in your case, you have the question, why the echo state wasn't restored.
This seems to be a special case of using (goto) and later call another batch file