如何在 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
How do I conditionally turn @ECHO ON/OFF in a Windows batch file?
提问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 OFF
so that your console isn't full of debug strings. On the build server, I'd rather have @ECHO ON
so 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 IF
statement 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 echo
command will hide the echo
command itself, but not the if
command 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 echo
command will slurp up the rest of the tokens on the line as its arguments, so the else echo off
part will not be interpreted by CMD
. Since CMD.EXE echoes by default it prints the if
command, and then either executes a single echo
command 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_PROJECT
is 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 off
at an interactive CMD
session prompt will cause it to stop showing the prompt. Which is a tad disconcerting, if not expected. Typing echo on
will 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.EXE
program 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 ECHO
is on by default, so you'll get the IF
statement 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