防止子输出转发中的cmd.exe

时间:2014-05-08 13:47:17

标签: io cmd

cmd.exe /C start  calc.exe > NUL 2> NUL
echo This line is shown immediately! 
cmd.exe /C start calc.exe > NUL 2> NUL | find "Parsing whole output"
echo This line won't execute until second calc.exe is closed! Why???

如何从cmd.exe启动后台应用程序,以便在退出后立即关闭cmd的输出(忽略子状态及其输出)?

已完成Cmd的输出,但我并不关心孩子的过程输出。

解释

  • parent - 调用子项并使用其输出的脚本或程序
  • child - 一个cmd命令或批处理文件,可选择生成一些输出
  • 孙子 - 一个由孩子调用并永久运行的程序

父和孙有固定的语义,不属于这个问题范围。我试图创造一个孩子。

验收标准

编写一个子批处理脚本,如果调用:

REM This is a parent
call child.cmd | find "something"
echo "Accepted!"
  • 让calc.exe孙子永远运行
  • 立即返回,让echo指令执行

1 个答案:

答案 0 :(得分:1)

已编辑 - 我将OP代码与我的混合,解释错误。我的错?

第一行调用控制台应用程序(cmd.exe),运行批处理文件的当前控制台实例将等待它结束。新的cmd将启动一个Windows应用程序而不等待它自己结束和结束,因此继续执行当前批处理文件。

第二行在启动calc命令的新cmd实例和find命令之间创建管道。新的cmd实例启动一个Windows应用程序而不等待它结束并结束自己将calc和find命令绑定在由第一个cmd实例处理的管道中。在管道中涉及的至少一个进程结束之前,管道处于活动状态,并且处理管道的第一个cmd实例无法继续。

start "" /b cmd.exe /C "calc.exe > NUL 2> NUL | find "Parsing whole output" "

启动cmd的控制台分离实例不会等待进程结束以继续处理当前批处理文件

如果原始行更改为(这是我首先检查的行和我的错误的来源)

cmd.exe /C  " start calc.exe > NUL 2> NUL | find "Parsing whole output"  "

然后管道将由第二个cmd实例处理,直到三个进程中的任何一个(第二个cmd,calc,find)结束,第一个cmd实例将不会继续,因为它正在执行等待它的控制台应用程序结束,直到管道结束它才会结束。

已编辑查看接受的新定义和标准,这是child.cmd

@if (@This==@IsBatch) @then
@echo off
    wscript //E:JScript "%~dpnx0"
    exit /b
@end
WScript.CreateObject('WScript.Shell').Run('calc.exe');

从cmd开始,任何已启动的进程都会继承输入和输出句柄的重定向,直到我们能够从cmd中获取某些内容。因此,启动一个流程(在这种情况下wscript,但cscript也可以),并从这里开始所需的元素(在这种情况下为calc),我们达到了所需的行为。