Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 589
Aaron Avatar asked Mar 18 '16 18:03

Aaron


People also ask

What is inherit handle?

An inherited handle refers to the same object in the child process as it does in the parent process. It also has the same value and access privileges.

What is start command in terminal?

In computing, start is a command of the IBM OS/2, Microsoft Windows and ReactOS command-line interpreter cmd.exe (and some versions of COMMAND.COM) to start programs or batch files or to open files or directories using the default program.

What is start command in batch?

In a batch script, a START command without /wait will run the program and just continue, so a script containing nothing but a START command will close the CMD console and leave the new program running. Document files can be invoked through their file association just by typing the name of the file as a command.

What is the parent process of CMD EXE?

bat ). Typically, when a user runs a command prompt, the parent process is explorer.exe or another instance of the prompt. There may be automated programs, logon scripts, or administrative tools that launch instances of the command prompt in order to run scripts or other built-in commands.


1 Answers

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

like image 102
dbenham Avatar answered Nov 15 '22 05:11

dbenham