Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't @ECHO ON/OFF work within a batch file IF block?

@echo on and @echo off don't seem to have any affect when executed within a bracketed if block in a batch file. Here's a simple demo:

@echo off
echo Test #1
if 1 == 1 (
  @echo on
  echo Test #2
  @echo off
  echo Test #3
)
@echo on
echo Test #4

The output from running the above on the command line is:

Test #1
Test #2
Test #3
C:\mybatchfilelocation>echo Test #4
Test #4

Could anyone explain this and/or suggest a workaround? (Expect it could probably be fixed by copious use of goto and labels but would prefer to continue using bracketed if blocks if possible...)

like image 253
Steve Chambers Avatar asked Jan 18 '16 11:01

Steve Chambers


2 Answers

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
like image 72
dbenham Avatar answered Sep 28 '22 01:09

dbenham


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 gotos and labels may be the only workable solution.

like image 24
Steve Chambers Avatar answered Sep 28 '22 01:09

Steve Chambers