【问题标题】:Why is here difference in this 2 cases of command execution?为什么这两种命令执行情况有所不同?
【发布时间】:2019-09-12 07:16:19
【问题描述】:

我需要用双引号并行运行两个命令(简单的命令在我的情况下不起作用)并等待结果。但是当我这样做时,我会在双重 qouted 执行时得到不同的行为(我的命令根本不会因为未知原因运行)。

我已将问题简化为以下示例:

(
   start "task1" cmd /C "timeout /t 5 /nobreak > nul"
   start "task2" cmd /C ""timeout /t 8 /nobreak > nul""
) | pause

你可以看到在后面的情况下计数器会倒计时,但在第一种情况下不会

Waiting for 8 seconds, press CTRL+C to quit ...

问题:

  • 是什么导致了这两种情况之间的变化?
  • 如何避免这种改变的行为?

在我的特殊情况下:

当我运行它时,一切正常:

start "task1" cmd /C ""D:\Program Files\Alteryx\bin\AlteryxEngineCmd.exe" "^<WizardValues^> ^<Module^>D:\long path\aaa.yxwz^</Module^> ^<Value name='Drop Down (31)'^>2019-08^</Value^> ^</WizardValues^>" > outp1.txt "

当我把简单的版本变成复杂的版本时,执行就会失败:

(
   start "task1" cmd /C ""D:\Program Files\Alteryx\bin\AlteryxEngineCmd.exe" "^<WizardValues^> ^<Module^>D:\long path\aaa.yxwz^</Module^> ^<Value name='Drop Down (12)'^>2019-08^</Value^> ^</WizardValues^>" > outp1.txt "
   start "task2" cmd /C ""D:\Program Files\Alteryx\bin\AlteryxEngineCmd.exe" "^<WizardValues^> ^<Module^>D:\long path\bbb.yxwz^</Module^> ^<Value name='Drop Down (34)'^>2019-07^</Value^> ^</WizardValues^>" > outp2.txt "
) | pause

问题:

  • 这种行为变化与上述示例有何相似之处?

【问题讨论】:

  • 您的第一个示例在第二行有双双引号,使重定向到nul 无效。去掉双引号,两个窗口都不会显示超时。
  • 那么对于第二个例子,你为什么要start实例cmd?您需要了解重定向到输出的命令来自哪个命令。因此,当您想在窗口中给出任务名称时,请从行中完全删除 cmd /c 并修复您的引用。
  • 是的,因为您的引用。我没有你的命令,但试试start "task2" "D:\Program Files\Alteryx\bin\AlteryxEngineCmd.exe" ^"^&lt;WizardValues^&gt; ^&lt;Module^&gt;D:\long path\bbb.yxwz^&lt;/Module^&gt; ^&lt;Value name='Drop Down (34)'^&gt;2019-07^&lt;/Value^&gt; ^&lt;/WizardValues^&gt;^" ^&gt; outp2.txt
  • 第一个命令是错误的。您在第一行添加了正确的引号,这是正确的。在第二行添加双双引号,这将打开和关闭并打开关闭。因为您正在重定向到 nul,所以您的第二个命令不会因为引用问题而重定向,第一个命令没有问题并正确重定向到 nul
  • 去掉^&gt; outp1.txt的转义

标签: windows batch-file cmd command-line escaping


【解决方案1】:

关于您的测试场景:

cmd /C "timeout /t 5 /nobreak &gt; nul" 中,redirection operator &gt; 对托管cmd 实例(运行批处理文件代码的实例)隐藏,因此它会在内部cmd 实例中执行。

cmd /C ""timeout /t 5 /nobreak &gt; nul"" 中,&gt; 暴露给宿主cmd 实例,因此在那里执行重定向,内部的不会收到&gt; nul 部分。
(虽然让我有点吃惊的是,双引号并没有出现语法错误;我可以想象第二个start 命令实际上接收到类似""timeout /t 5 /nobreak 的内容来执行,它似乎删除了前导""来自,但我不太确定。)


关于您的特殊情况:

忘记在您的类似 XML 的字符串中使用 escaping,只需转义外部引号和重定向运算符。

  • 单独运行程序:

    start "task1" cmd /C ^""D:\Program Files\Alteryx\bin\AlteryxEngineCmd.exe" "<WizardValues> <Module>D:\long path\aaa.yxwz</Module> <Value name='Drop Down (31)'>2019-08</Value> </WizardValues>" ^> "outp1.txt"^"
    
  • 在管道 (|) 中运行程序需要双重转义,因为这里的任一端都由 cmd /S /D /c 自己执行:

    (
        start "task1" cmd /C ^^^""D:\Program Files\Alteryx\bin\AlteryxEngineCmd.exe" "<WizardValues> <Module>D:\long path\aaa.yxwz</Module> <Value name='Drop Down (12)'>2019-08</Value> </WizardValues>" ^^^> "outp1.txt"^^^"
        start "task2" cmd /C ^^^""D:\Program Files\Alteryx\bin\AlteryxEngineCmd.exe" "<WizardValues> <Module>D:\long path\bbb.yxwz</Module> <Value name='Drop Down (34)'>2019-07</Value> </WizardValues>" ^^^> "outp2.txt"^^^"
    ) | pause ^> nul
    

不幸的是,您不能只省略(转义的)外部引号对,因为cmd 在处理它们时不是很聪明。像cmd /C "program.exe" "quoted string" 这样的东西留下了命令行program.exe" "quoted string,这当然是无效的语法。

N. B.:
通常可以在不使用cmd /C 的情况下启动外部程序,但在您的情况下,您使用的是输出重定向&gt;,这是cmd 内部的东西,这就是您需要它的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 2011-01-08
    • 2015-11-27
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    相关资源
    最近更新 更多