我有一个批处理文件,可以在本地运行,也可以在构建服务器上运行,以完成某些有趣的工作。在本地计算机上,我想要@ECHO OFF
,以便您的控制台没有充满调试字符串。在构建服务器上,我宁愿拥有@ECHO ON
,以便可以调查失败。
如果存在特殊环境变量(TEAMCITY_PROJECT_NAME
),则可以确定构建服务器上下文。所以,我以为我可以做类似
IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON ELSE @ECHO OFF
但是,这不起作用,我得到了IF
声明与其他一切相呼应......有什么想法吗?
答案 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