如何在Windows批处理文件中有条件地打开/关闭@ECHO?

时间:2013-06-21 17:31:36

标签: windows parsing batch-file cmd echo

我有一个批处理文件,可以在本地运行,也可以在构建服务器上运行,以完成某些有趣的工作。在本地计算机上,我想要@ECHO OFF,以便您的控制台没有充满调试字符串。在构建服务器上,我宁愿拥有@ECHO ON,以便可以调查失败。

如果存在特殊环境变量(TEAMCITY_PROJECT_NAME),则可以确定构建服务器上下文。所以,我以为我可以做类似

的事情
IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON ELSE @ECHO OFF

但是,这不起作用,我得到了IF声明与其他一切相呼应......有什么想法吗?

4 个答案:

答案 0 :(得分:15)

该命令实际上未命名为@echo@是一个可选标志,在语句开头有效,表示该语句的回声被抑制。因此,对@命令的每个引用使用echo将隐藏echo命令本身,但不隐藏它之前的if命令。

但实际上导致命令无法按预期运行的问题是第一个echo命令会将该行的其余标记作为其参数,因此else echo off部分不会被CMD解释。由于CMD.EXE默认回声,它会打印if命令,然后执行单个echo命令或什么都不执行。由于@if的主体语句的开头有意义,因此不会打印echo命令。

通常,解决方案是使用括号来分隔命令边界。但是,由于默认情况下启用了echo,并且如果未定义TEAMCITY_PROJECT,您实际上只想抑制它,我们可以直接说出来。

@IF NOT DEFINED TEAMCITY_PROJECT_NAME ECHO OFF

我在开头留下了一个@来抑制此行的回显,因此该行不会出现在服务器的日志中。

相关说明

回声状态也适用于交互式会话。在交互式echo off会话提示符下键入CMD将导致其停止显示提示。如果没有预料到,这有点令人不安。键入echo on将恢复正常行为。

更多关于解析

(为了清楚起见,我已经编辑了前面的部分,并添加了此部分以尝试记录实际发生的情况。)

解释.BAT和.CMD脚本的CMD.EXE程序,并在现代Windows中提供交互式命令提示符,在有效地未记录的情况下,记录得非常好。我试图搜索一份官方文件,说明该标志具有这种效果以及确切的使用位置,但这种尝试基本上没有成功。

从实验中可以清楚地看出,如果at符号显示为命令的第一个非空白字符,则会对其进行解析和解释。我试图通过使用上面的“开头的陈述”来表达这一点。

据我所知,没有针对CMD语言发布的正式语法。但是我们从CDM本身的文档(类型cmd /?到提示)以及if /?以及其他“有趣”内置命令的内置帮助文本中知道了在CMD解析其源文本时遵循。

命令的开头似乎位于一行的开头,或者在if的条件之后,else之后,或在开括号(之后。一旦识别出at-sign,它就适用于该命令的(大部分)余额。

自己尝试下面的批处理文件,并在移动at符号的同时玩,你会很快意识到规则很难准确说明:

rem this remark will echo
@rem this one will not
@ rem neither will this
 @rem nor this one
@rem the if command (and else) will echo, but not either echo command
if exist q17241089.bat ( @ echo saw q17241089.bat ) else @ echo foo
if not exist q17241089.bat ( @ echo no q17241089.bat ) else @ echo bar
@ rem none of the following command is echoed
@ if exist q17241089.bat ( @ echo saw q17241089.bat ) else @ echo spam

在我的Win 7 Pro上运行时,我看到:

C...>
C...>q17241089.bat

C...>rem this remark will echo

C...>if exist q17241089.bat ()  else
saw q17241089.bat

C...>if not exist q17241089.bat ()  else
bar
saw q17241089.bat
C...>

与BAT文件的大部分细节一样,在你划伤的任何表面下都有一个谜。

答案 1 :(得分:4)

设置括号(见文件......):

IF DEFINED TEAMCITY_PROJECT_NAME (@ECHO ON) ELSE @ECHO OFF

答案 2 :(得分:2)

好吧,默认情况下似乎ECHO处于启用状态,因此无论如何,只要您测试该条件,您就会获得IF语句输出。你应该从

开始
@ECHO OFF

并将条件添加为另一个评估语句

@ECHO OFF && IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON

答案 3 :(得分:1)

如前面的回复中所述,默认情况下,ECHO处于启用状态。实现相同行为的另一种方法是:

@if "%TEAMCITY_PROJECT_NAME%" == "" @echo off