为什么这两种命令执行情况会有所不同?
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
内部的东西,这就是您需要它的原因。
我需要 运行 两个带双引号的命令(简单的命令在我的情况下不起作用)并等待结果。但是当我这样做时,我得到了一个不同的行为,双引号执行(我的命令根本不会 运行 由于未知原因)。
我已经将问题简化为这个例子:
(
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
内部的东西,这就是您需要它的原因。