Why doesn't @ECHO ON/OFF work within a batch file IF block?
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
Have just found out what is causing this by turning the echo on before an if
block.
@echo on
if 1 == 1 (
echo Test #1
echo Test #2
)
This outputs:
C:\mybatchfilelocation>if 1 == 1 (
echo Test #1
echo Test #2
)
Test #1
Test #2
So the statement that is echoed is the entire if block rather than each statement within it. This answer explains this further and this answer gives a workaround - unfortunately not what I wanted to hear but it looks like lots of goto
s and labels may be the only workable solution.
You could do something like this to achieve the result you want:
@echo off
set "ExecuteCmd=echo Test #2"
echo Test #1
if 1 == 1 (
echo %ExecuteCmd%
%ExecuteCmd%
echo Test #3
)
@echo on
echo Test #4