【问题标题】:Programmatically writing a batch file to echo to stderr以编程方式编写批处理文件以回显到 stderr
【发布时间】:2016-01-03 17:35:13
【问题描述】:

作为我正在进行的一些集成测试的一部分,我需要编写一个批处理文件,该批处理文件在 windows 框上回显到 stderr。目前我正在使用以下命令:

md %UserProfile%\tests\e3f949d1219d4cad9288bf88d0fcc906\ && cd %UserProfile%\tests\e3f949d1219d4cad9288bf88d0fcc906\ && ( echo @echo off  && echo 'echo This is error line 1 1>&2' && echo 'echo This is error line 2 1>&2' && echo @echo on ) >>test-stderrout.bat

这应该在%UserProfile%\tests\ 目录下创建一个临时目录。然后导航到这个临时工作目录。然后使用以下代码创建一个批处理文件:

@echo off
echo This is error line 1 1>&2
echo This is error line 2 1>&2
@echo on

但是,文件包含:

@echo off
@echo on

我看到第一个回显被传送到标准错误中,而不是作为文本读取然后在批处理文件中。是否有可能以某种方式转义以允许输出包含重定向语句?

【问题讨论】:

  • 一些特殊字符必须被转义。试试看:echo echo This is some text 1^>^&2

标签: batch-file stderr


【解决方案1】:

我假设 windows shell 的工作方式或多或少类似于 *nix shell。

md %UserProfile%\tests\e3f949d1219d4cad9288bf88d0fcc906\ && cd %UserProfile%\tests\e3f949d1219d4cad9288bf88d0fcc906\ && echo @echo off >>test-stderrout.bat && echo 'echo This is error line 1 1>&2' >>test-stderrout.bat  && echo 'echo This is error line 2 1>&2'>>test-stderrout.bat  && echo @echo on >>test-stderrout.bat

您正在创建一个子 shell 并在其中做一些事情,而不是按照您的意图做,将每个命令回显到 test-stderrout.bat 文件。

我对 windows shell 并不积极,但在我看来,这就像发生了什么,所以只要你转储 () 并将字符串回显到文件中,它应该都可以工作。可能更优雅的方式来做到这一点,但我认为这会奏效。

或者您可以遵循更好的字符串实践,并始终将 echo 放入 '..',这是我在 shell 脚本中经常做的以避免错误。

md %UserProfile%\tests\e3f949d1219d4cad9288bf88d0fcc906\ && cd %UserProfile%\tests\e3f949d1219d4cad9288bf88d0fcc906\ && echo '@echo off' >>test-stderrout.bat && echo 'echo This is error line 1 1>&2' >>test-stderrout.bat  && echo 'echo This is error line 2 1>&2'>>test-stderrout.bat  && echo '@echo on' >>test-stderrout.bat

【讨论】:

  • 批处理工作方式不同。 a) echo 'string' 将在输出中包含单引号(并在您尝试运行结果文件时导致语法错误) b) (echo one & echo two)>file.txt just writes one` 和 twofile.txt。没有简单的variable=(command) 将命令输出放到批处理中的变量中。
【解决方案2】:

试试这个:

md c:\e3f949d1219d4cad9288bf88d0fcc906\ & cd C:\e3f949d1219d4cad9288bf88d0fcc906 & echo @echo off >> test-stderrout.bat & echo echo This is error line 1 1^>^&2 >> test-stderrout.bat & echo echo This is error line 2 1^>^&2 >> test-stderrout.bat & echo @echo on >> test-stderrout.bat

在本地测试它似乎可以正常工作。

秘诀是在你的回声中用^ 转义>& 字符。

【讨论】:

  • 我刚刚意识到斯蒂芬已经在我面前以评论的形式回答了你的问题。抱歉,我不是故意要窃取你的答案 Stephan。
【解决方案3】:

以下行应该做你想做的事:

md "%UserProfile%\tests\e3f949d1219d4cad9288bf88d0fcc906\" && cd /D "%UserProfile%\tests\e3f949d1219d4cad9288bf88d0fcc906\" && ((echo @echo off) & (echo echo This is error line 1 1^>^&2) & (echo echo This is error line 2 1^>^&2) & (echo @echo on)) >> test-stderrout.bat

对代码的更改:

  • 目录路径包含在"" 中,以避免出现空格问题;
  • /D 添加到cd 以在必要时更改驱动器(我不知道您当前的驱动器);
  • echo 行中的 >&^>^& 一样被转义,以便逐字回显;
  • 每个echo 命令都包含在() 中以避免尾随空格;
  • &&(条件命令分隔符)被&(无条件命令分隔符)替换,因为&&echo 命令之间没有意义;我将它保存在mdcd 以避免在由于某种原因无法创建目录的情况下回显;

【讨论】:

  • ... 和单个 &&& 足够(并且可能更好)
  • 真的,@Stephan,谢谢,我会更改它,除了md/cd,如果由于某种原因无法创建目录,这可能是有意义的...
  • 感谢您的详细回复,其中包含对我遇到的问题的每个单独的修复。
猜你喜欢
  • 2010-10-27
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多