How do I use the “start” command without inheritin

2019-01-25 17:04发布

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?

1条回答
贪生不怕死
2楼-- · 2019-01-25 17:49

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:

start notepad | findstr "^"

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

@echo off
call :test >nul
echo done calling test.bat
exit /b

:test
start notepad

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:

C:\test>test.bat >test.txt

C:\test>REM The command returns immediately, and notepad remains open

C:\test>type test.txt
done calling test.bat

C:\test>echo This fails as long as notepad remains open >test.txt
The process cannot access the file because it is being used by another process.

C:\test>type test.txt
done calling test.bat

C:\test>REM Now I close notepad

C:\test>echo This works once notepad is closed >test.txt

C:\test>type test.txt
This works once notepad is closed

C:\test>

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."

查看更多
登录 后发表回答