This is a minimal example that illustrates my problem:
:: test.bat
@echo off
call test2.bat 2>&1 | findstr foo
echo done calling test2
:: test2.bat
@echo off
start /B notepad >NUL
echo done starting child process
In this sample, findstr will not complete until notepad is closed, presumably because notepad has inherited stdout from the parent cmd process. How can I modify test2.bat so that test.bat doesn't hang?
I believe I can illustrate the problem without any batch file at all. The following pipe construct does not complete until after notepad.exe is closed:
I would expect that notepad would be executing in a new process that is totally disassociated from the cmd.exe pipe, and the only thing being piped would be the output of the START command itself (which is none). The START command returns "instantly", yet the pipe remains open for as long as notepad is running.
I don't know if it is an inherited I/O stream that is keeping the pipe open, but I can prove that the notepad process is inheriting streams in a way that might be the root of the problem. This is basically the same issue that was brought up at Issue with output redirection in batch.
Here is a simple batch script: test.bat
Notice that stdout has been redirected to NUL when notepad is STARTed, due to the redirection of
call :test >nul
.Now look at what happens when I issue a series of commands from the command line, starting off with test.bat having stdout redirected to a file:
I am still blown away by this behavior. It seems totally illogical.
I don't think there is any way to prevent the stream inheritance with cmd.exe.
Perhaps Harry Johnston's suggestion could solve the issue (from the question comments): "I'd write a very simple executable to call CreateProcess with inheritance disabled."