As you have discovered, the changed ECHO state is not recognized by the parser until it reaches a statement that is after the code block that contains the ECHO ON/OFF.
But there is one exception - the commands after FOR ... DO do take on the state change within the same block :-)
Note that you only need @
to suppress command output when ECHO is currently ON. If it is OFF, then there is no need for @ECHO ON
. And if you turn it ON and OFF within the same code block, then you don't need it there either.
Here is a demo that echos the even test lines:
@echo off
echo Test #1
(
echo on
for %%. in (.) do echo Test #2
echo off
echo Test #3
echo on
for %%. in (.) do echo Test #4
echo off
echo Test #5
)
echo on
echo Test #6
@echo off
echo Test #7
-- OUTPUT --
Test #1
C:\test>echo Test #2
Test #2
Test #3
C:\test>echo Test #4
Test #4
Test #5
C:\test>echo Test #6
Test #6
Test #7
You might find it convenient to declare a simple echo_on
"macro". The following produces the exact same output:
@echo off
setlocal
set "echo_on=echo on&for %%. in (.) do"
echo Test #1
(
%echo_on% echo Test #2
echo off
echo Test #3
%echo_on% echo Test #4
echo off
echo Test #5
)
echo on
echo Test #6
@echo off
echo Test #7