该命令实际上没有命名@echo
。这@
是一个在语句开头有效的可选标志,表示该语句的回显被抑制。因此,@
对命令的每个引用使用 onecho
将隐藏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 脚本并在现代 Windows 中提供交互式命令提示符的CMD.EXE
程序出人意料地有很好的文档记录,而实际上却没有记录。我试图搜索一份官方文件,解释 at 标志具有这种效果以及它可以在哪里使用,但基本上没有成功。
从实验中可以清楚地看出,如果 at 符号作为命令的第一个非空白字符出现,则它会被解析和解释。我试图通过使用上面的“语句开头”这个短语来表达这一点。
据我所知,没有针对 CMD 语言发布的正式语法。但是我们确实从 CDM 本身的文档(键入cmd /?
提示符)以及if /?
其他“有趣”内置命令的内置帮助文本中知道,当 CMD 解析其源文本时需要遵循一些规则。
命令的开头似乎位于行首,或在条件条件if
之后,在 之后else
,或在左括号之后(
。一旦识别出 at 符号,它就会应用于该命令的(大部分)余额。
自己尝试以下批处理文件,并尝试移动 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 文件的大多数细节一样,您在任何表面下都存在一个谜。