1
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???

How do I start a background application from cmd.exe so that cmd's output is immediately closed after exit (ignoring child state and its output)?

Cmd's output is processed, but I don't care about child's process output.

Definitions

  • parent - a script or program that invokes a child and consumes its output
  • child - a cmd command or batch file optionally producing some output
  • grandchild - a program that is invoked by a child and is left running forever

Parent and grandchild have fixed semantics and are out of this question scope. I'm trying to create a child.

Acceptance criteria

Write a child batch script that, if invoked with:

REM This is a parent
call child.cmd | find "something"
echo "Accepted!"
  • leaves calc.exe grandchild running forever
  • returns immediately, letting echo directive execute
Basilevs
  • 22,440
  • 15
  • 57
  • 102
  • Related: [Nohup on windows](http://stackoverflow.com/questions/3382082/whats-the-nohup-on-windows), [Running non-child process](http://stackoverflow.com/questions/1536205/running-another-program-in-windows-bat-file-and-not-create-child-process) – Basilevs May 08 '14 at 13:49

1 Answers1

1

EDITED - I mixed the OP code with mine and the explanation was wrong. My fault

The first line calls a console application (cmd.exe), and current console instance running the batch file will wait for it to end. The new cmd will start a windows application without waiting for it to end and end itself, so execution in current batch file continues.

The second line creates a pipe between a new cmd instance starting a calc command and the find command. New cmd instance starts a windows application without waiting for it to end and end itself leaving the calc and the find command tied in a pipe handled by the first cmd instance. Until at least one of the processes involved in the pipe ends, the pipe is alive and the first cmd instance that is handling the pipe can not continue.

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

Starting a console detached instance of cmd will not wait for the process to end to continue processing the current batch file

If the original line is changed to (this was the line that at first i checked and the origin of my error)

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

then the pipe will be handled by the second cmd instance, and until any of the three processes (second cmd, calc, find) ends, the first cmd instance will not continue as it is executing a console application waiting for it to end, and it will not end until the pipe ends.

EDITED Seen the new definition and criteria for acceptance, this is child.cmd

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

From cmd, any started process inherits the redirection of the input and output handles until we are able to reach something out of cmd. So starting a process (wscript in this case but cscript will also work) and from here starting the desired element (calc in this case), we reach the required behaviour.

MC ND
  • 69,615
  • 8
  • 84
  • 126
  • Second cmd terminates immediately too. This can be verified with Task Manager. And the idea of pipe being handled by child cmd feels suspicious to me. – Basilevs May 09 '14 at 17:54
  • @Basilevs, you are right, when testing i take one of my changes as the original line. My fault. Answer corrected. – MC ND May 09 '14 at 20:12
  • You detach find, which serves a detachment indicator. Please refactor the code to look like your_arbitary_which_starts_calc_exe | find "Output". Find should not be detached - it is used to indicate that child process doesn't hang consumer of its output. – Basilevs May 10 '14 at 03:18
  • I mean - find is used to indicate that grandchild does not affect consumer of child output. Sorry. – Basilevs May 10 '14 at 03:32
  • @Basilevs, sorry, i understand nothing. But reading your last comment i realized that i don't know which output do you want the find command to process, if the second cmd output, the calc output, or what, nor what is the purpose/meaning of the code. And i think i am walking in circles around something not well defined. Can you better define what is the desired functionality of the code? – MC ND May 10 '14 at 07:30
  • @Basilevs, anyway, the included code does not detach find, detachs second instance of cmd. In all the code lines find is always inside a pipe and the difference is the instance of cmd that is handling the pipe. When the pipe is handled by the second instance of cmd, the full tree of processes can be detached from initial cmd process. When pipe is handled by first instance of cmd, it can not continue until the pipe ends. And any pipe in batch files NEEDS an instance of cmd that handle it. So, if a pipe is needed, the rest is to determine which instance of cmd will handle it. – MC ND May 10 '14 at 07:36
  • I've updated the question with definitions and acceptance criteria. Feel free to ask for further clarifications. – Basilevs May 10 '14 at 15:46
  • @Basilevs, limiting the operation to `cmd.exe` alone i don´t know any way to do it as the handles of the input and output streams are automatically inherited between processes. But the child.cmd included in answer uses nothing out of the OS but needs to use the scripting engine. – MC ND May 10 '14 at 16:49