批处理:为什么追加文本文件时会输出“ECHO is off”?

5

我写了一批处理程序,其中包含一些代码,用于检查它已经运行了多少次,方法是读取一个文本文件,然后将新的、增加的数字写回到该文本文件中。

@ECHO OFF
for /f "delims=" %%x in (TimesRun.txt) do set Build=%%x
set Build=%Build%+1
@echo Build value : %Build%
echo %Build%>>TimesRun.txt
Pause

这确实可以将文本文件追加,但它会添加"1+1"。我太傻了!我忘记使用/a开关来启用算术运算!但是当我相应地更改代码时...

@ECHO OFF
for /f "delims=" %%x in (TimesRun.txt) do set Build=%%x
set /a Build=%Build%+1
@echo Build value : %Build%
echo %Build%>>TimesRun.txt
Pause

...有趣的事情发生了:我想将文件追加,但是控制台却输出了 ECHO is off.。我知道通常这种情况发生在使用ECHO时没有文本或空变量的情况下。我已经添加了第一个@echo Build value : %Build%来检查变量Build是否为空;它不为空,计算也正确执行了。
我已经发现

后面缺少内容,请提供完整的待翻译文本。
>>TimesRun.txt (echo %Build%)

虽然我不明白为什么,但这确实带来了期望的结果。

echo %Build%>>TimesRun.txt

然而,我错过了什么吗?
3个回答

6

你无意中指定了一个重定向句柄。


重定向 允许你指定一个定义将要重定向的内容的句柄:

0     = STDIN  (keyboard input)
1     = STDOUT (text output)
2     = STDERR (error text output)
3 ~ 9 = undefined

对于输入重定向运算符<,默认使用句柄0;对于输出重定向运算符>>>,默认句柄为1

您可以通过在重定向运算符前放置单个数字来明确指定句柄;例如,2>定义将错误文本输出重定向。


在您的echo命令行中,当%Build%是一个单独的数字,比如1时,您无意中正好这样做:

echo 1>>TimesRun.txt

为了避免这种情况,您有以下几个选择:
  1. To reverse the statement so that the redirection definition comes first:

    >>TimesRun.txt echo %Build%
    

    This is the most general and secure way of doing redirections.

  2. To enclose the redirected command in parentheses:

    (echo %Build%)>>TimesRun.txt
    

    This also works safely.

  3. To put a SPACE in front of the redirection operator:

    echo %Build% >>TimesRun.txt
    

    This works too, but the additional SPACE is included in the output of echo.

请参阅这篇优秀的文章:cmd.exe 重定向运算符的顺序和位置


0

批处理文件重定向可以自定义以指定输出位置。

command 1>file.txt 将 STDOUT 的输出重定向到 file.txt
command 2>file.txt 将 STDERR 的输出重定向到 file.txt

你的构建值是1,所以不小心告诉 CMD 把 echo 的输出发送到 TimesRun.txt - 当你单独运行 echo 时,它会打印出它的状态(开启或关闭)。

你也可以说 echo %Build% >>TimesRun.txt ,空格将防止 Build 的值被视为重定向命令。


0

Microsoft的文章使用命令重定向运算符解释了三个标准句柄以及如何将它们重定向到另一个句柄、命令、设备、文件或控制台应用程序。

将写入句柄1(STDOUT)的输出重定向到文件应该只需使用:

  • > ... 如果文件不存在则创建文件,否则覆盖现有文件,或者
  • >> ... 如果文件不存在则创建文件,否则追加到现有文件。

重定向运算符通常附加在命令行的末尾。但是,在使用命令ECHO并且输出到STDOUT的字符串以1到9结尾的情况下,这会导致问题。

其中一种解决方案是在命令行开头指定重定向:

@for /F "delims=" %%x in (TimesRun.txt) do @set Build=%%x
@set /A Build+=1
@echo Build value : %Build%
>>TimesRun.txt echo %Build%

在命令提示符窗口中执行此小批处理文件,而不是在顶部使用@echo off,将显示Windows命令处理器在对每行进行文本文件TimesRun.txt预处理后执行的内容,该文件当前包含值0或根本不存在。

echo 1 1>>TimesRun.txt

可以看出,Windows命令解释器通过在插入一个空格和将1留在>>左侧来将重定向移动到行末。

使用上述批处理代码后,真正执行的带有>>的行是经过预处理的:

echo 2 1>>TimesRun.txt

指定以 1>> 结尾的重定向,即在批处理文件中使用
echo %Build%1>>TimesRun.txt

这也不是一个好主意,因为这会导致在第一次运行时执行该行:

echo 11 1>>TimesRun.txt

所以文件中写入的是11而不是1。可以通过在>>1>>之前插入一个空格来避免这种错误的输出,即使用其中之一:

echo %Build% >>TimesRun.txt
echo %Build% 1>>TimesRun.txt

但是在%Build%之后的空格也会被写入文件,因为实际执行的是:

echo 1  1>>TimesRun.txt

尾随空格在这里不会有问题,但仍然应该避免使用。

注意:在使用算术运算时,即set /A ...,任何不是数字或运算符的字符串都会自动解释为变量名,并且此变量的当前值用于计算算术表达式。因此,在使用仅由单词字符组成并以字母字符开头的环境变量名称进行set /A之后,不应在算术表达式中使用%...%!...!。这在命令SET的帮助输出中得到了解释,可以在命令提示符窗口内运行set /?来查看。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接