9

我有一个可以在本地或构建服务器上运行的批处理文件来做一些有趣的工作。在本地机器上,我希望@ECHO OFF您的控制台不会充满调试字符串。在构建服务器上,我宁愿有@ECHO ON这样的故障可以调查。

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

IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON ELSE @ECHO OFF

但是,这行不通,我得到的IF声明与其他所有内容都有呼应……有什么想法吗?

4

4 回答 4

15

该命令实际上没有命名@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 文件的大多数细节一样,您在任何表面下都存在一个谜。

于 2013-06-21T17:40:10.600 回答
4

设置括号(参见文档...):

IF DEFINED TEAMCITY_PROJECT_NAME (@ECHO ON) ELSE @ECHO OFF
于 2013-06-21T19:00:48.360 回答
2

好吧,似乎默认情况下它是打开的,所以无论如何你测试那个条件ECHO你都会得到语句输出。IF你应该从

@ECHO OFF

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

@ECHO OFF && IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON
于 2013-06-21T17:37:51.853 回答
2

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

@if "%TEAMCITY_PROJECT_NAME%" == "" @echo off
于 2016-08-08T14:44:31.663 回答