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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17241089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 10:36:54  来源:igfitidea点击:

How do I conditionally turn @ECHO ON/OFF in a Windows batch file?

windowsparsingbatch-filecmdecho

提问by Anthony Mastrean

I have a batch file that can be run locally or on the build server to do some kind of interesting job. On the local machine, I want @ECHO OFFso that your console isn't full of debug strings. On the build server, I'd rather have @ECHO ONso that failures can be investigated.

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

The build server context can be determined if a special environment variable exists (TEAMCITY_PROJECT_NAME). So, I thought I could do something like

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

IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON ELSE @ECHO OFF

But, that's not working, I get the IFstatement echoed along with everything else... any thoughts?

但是,这是行不通的,我得到的IF声明与其他所有内容一起回响......有什么想法吗?

回答by RBerteig

The command is not actually named @echo. The @is an optional flag valid at the beginning of a statement to indicate that echo is suppressed for that statement. So using the @on each reference to the echocommand will hide the echocommand itself, but not the ifcommand that precedes it.

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

But the issue that is actually causing your command to fail to operated as expected is that the first echocommand will slurp up the rest of the tokens on the line as its arguments, so the else echo offpart will not be interpreted by CMD. Since CMD.EXE echoes by default it prints the ifcommand, and then either executes a single echocommand or nothing. Since the @does have meaning at the start of the statement that is the body of the if, neither echo command would be printed.

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

In general, the solution to that is to use parenthesis to delimit the command boundaries. However, since echo is on by default and you really only want to suppress it if TEAMCITY_PROJECTis not define, we can say that directly.

通常,解决方案是使用括号来分隔命令边界。但是,由于默认情况下 echo 是打开的,并且您真的只想在TEAMCITY_PROJECT未定义时抑制它,因此我们可以直接说。

@IF NOT DEFINED TEAMCITY_PROJECT_NAME ECHO OFF

I've left a single @at the beginning to suppress echo of this line, and as a result this line will not appear in your server's logs.

@在开头留下了一个单曲来抑制这一行的回声,因此这一行不会出现在您的服务器日志中。

Related note

相关说明

The echo state also applies to an interactive session. Typing echo offat an interactive CMDsession prompt will cause it to stop showing the prompt. Which is a tad disconcerting, if not expected. Typing echo onwill restore normal behavior.

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

More on Parsing

更多关于解析

(I've edited the earlier section for clarity, and added this section to attempt to document what is really happening.)

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

The CMD.EXEprogram that interprets .BAT and .CMD scripts, and provides the interactive command prompt in modern Windows is surprisingly well documented while effectively being undocumented. My attempts to search for an official document explaining that the at-sign has this effect and exactly where it can be used have been largely unsuccessful.

CMD.EXE程序解释.BAT和.CMD脚本,并提供交互式命令现代的Windows提示,同时有效地被无证令人惊讶的是有据可查的。我试图寻找一份官方文件,解释 at 标志具有这种效果以及它可以在何处使用,但基本上没有成功。

It is clear from experimentation that the at-sign is parsed and interpreted if it appears as the first non whitespace character of a command. I've tried to express that by using the phrase "beginning of a statement" above.

从实验中可以清楚地看出,如果 at 符号作为命令的第一个非空白字符出现,它就会被解析和解释。我试图通过使用上面的短语“陈述的开头”来表达这一点。

As far as I can tell there is no formal grammar published for CMD's language. But we do know from the documentation for CDM itself (type cmd /?to a prompt) as well as if /?and the built-in help text for other "interesting" built-in commands that there are rules that are followed when CMD parses its source text.

据我所知,没有为 CMD 的语言发布正式的语法。但是我们确实从 CDM 本身的文档(键入cmd /?提示)以及if /?其他“有趣的”内置命令的内置帮助文本中知道,当 CMD 解析其源文本时,会遵循一些规则。

The start of a command appears to be at the beginning of a line, or after the conditional of an if, after the else, or after an open parenthesis (. Once the at-sign has been recognized, it applies to (most) of the balance of that command.

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

Try the following batch file yourself, and play with moving the at signs around and you'll quickly get the sense that the rules are hard to state precisely:

自己尝试以下批处理文件,并尝试四处移动 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

When run on my Win 7 Pro I see:

在我的 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...>

As with most of the fine details of BAT files, there is a mystery underneath any surface you scratch.

与 BAT 文件的大多数精细细节一样,您刮擦的任何表面下面都有一个谜。

回答by Endoro

set parentheses (see docu...):

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

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

回答by JoeG

As noted in earlier responses, ECHO is on by default. An alternative way of achieving the same behavior is:

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

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

回答by Anthony Mastrean

Well, it seems that ECHOis on by default, so you'll get the IFstatement output anyway you test that conditional. You should start with

好吧,似乎ECHO默认情况下是启用的,因此IF无论如何测试该条件,您都会获得语句输出。你应该从

@ECHO OFF

And add your conditional as another statement to evaluate

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

@ECHO OFF && IF DEFINED TEAMCITY_PROJECT_NAME @ECHO ON