How do I use the “start” command without inheriting handles in the child process?

后端 未结 1 1197
耶瑟儿~
耶瑟儿~ 2020-12-17 02:02

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
@         


        
相关标签:
1条回答
  • 2020-12-17 02:55

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

    0 讨论(0)
提交回复
热议问题