为什么@ECHO ON / OFF不在批处理文件IF块中工作?

时间:2016-01-18 11:07:55

标签: windows batch-file cmd echo

@echo on@echo off在批处理文件中的括号if块中执行时似乎没有任何影响。这是一个简单的演示:

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

在命令行上运行上面的输出是:

  

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

有人可以解释这个和/或建议一个解决方法吗? (预计可以通过大量使用goto和标签来修复它,但如果可能的话,我希望继续使用括号格式的框架......)

4 个答案:

答案 0 :(得分:6)

正如您所发现的那样,解析器无法识别更改的ECHO状态,直到它到达包含ECHO ON / OFF的代码块之后的语句。

但是有一个例外 - FOR ... DO之后的命令确实在同一个块中进行状态更改: - )

请注意,当ECHO当前为ON时,您只需要@来抑制命令输出。如果它是OFF,那么就不需要@ECHO ON。如果你在相同的代码块中打开和关闭它,那么你也不需要它。

这是一个回归偶数测试线的演示:

@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

- 输出 -

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

您可能会发现声明一个简单的echo_on"宏"很方便。以下产生完全相同的输出:

@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

答案 1 :(得分:2)

通过在 if块之前打开上的回声,刚刚找到了导致这种情况的原因。

@echo on
if 1 == 1 (
  echo Test #1
  echo Test #2
)

输出:

  

C:\ mybatchfilelocation>如果1 == 1(
  回声测试#1
   回声测试#2
  )
  测试#1
  测试#2

所以回显的语句是整个if块而不是其中的每个语句。 This answer进一步解释了这一点,this answer提供了一种解决方法 - 遗憾的是,我不想听到,但看起来很多goto和标签可能是唯一可行的解​​决方案。

答案 2 :(得分:2)

你可以做这样的事情来达到你想要的结果:

@echo off
set "ExecuteCmd=echo Test #2"
echo Test #1
if 1 == 1 (
  echo %ExecuteCmd%
  %ExecuteCmd%
  echo Test #3
)
@echo on
echo Test #4

答案 3 :(得分:1)

如何将echo控制命令放在子程序中?

@echo off
echo Test #1
if 1 == 1 (
  CALL :DO_ECHO_ON
  echo Test #3
)
@echo on
echo Test #4

@EXIT /B

:DO_ECHO_ON
@ECHO ON
echo Test #2
@ECHO OFF
@EXIT /B

这会产生我期望的输出。

Test #1

C:\secret>echo Test #2 
Test #2
Test #3

C:\secret>echo Test #4 
Test #4

基于您的一条评论,我想您希望能够为任意命令启用echo。这个修改过的版本可以做到这一点。

@echo off
echo Test #1
if 1 == 1 (
  CALL :DO_ECHO_ON_CMD echo Test #2
  echo Test #3
  CALL :DO_ECHO_ON_CMD dir /b "C:\Program Files"
  echo Test #3.1
  CALL :DO_ECHO_ON_CMD attrib c:\Windows
)
@echo on
echo Test #4

EXIT /B

:DO_ECHO_ON_CMD
@ECHO ON
%*
@ECHO OFF
@EXIT /B 0