为什么这两种命令执行情况会有所不同?

Why is here difference in this 2 cases of command execution?

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

我已经将问题简化为这个例子:

(
   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

问题:

关于您的测试场景:

cmd /C "timeout /t 5 /nobreak > nul"redirection operator > is hidden from the hosting cmd 实例(运行批处理文件代码的实例),因此它在内部 cmd 实例中执行。

cmd /C ""timeout /t 5 /nobreak > nul"" 中,> 暴露给宿主 cmd 实例,因此重定向在那里执行,内部的不接收 > 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 的情况下开始使用,但在您的情况下,您使用的是输出重定向 >,这是 cmd 内部的东西,这就是您需要它的原因。