in my python script i have several threads calling an application with subprocess like this:
arguments = ["start", "/min", "/w", "program", "prog_argument_1", "prog_argument_2", "etc"]
proc = subprocess.run(arguments , text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
i am calling the program with “start /min /w” so each execution has its own cmd window and i can bring it up to see the status or if it hung up somewhere or wants user input
however by doing so the retun value is always zero and the standard output and error are always empty, regardless of what the programm did. to improve my script and for successive operations i would like to recover them.
i tried doing like this
arguments = ["program", "prog_argument_1", "prog_argument_2", "etc"]
proc = subprocess.run(arguments , text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
in this case i have all the information i need in the proc variable but then the program is executed silently and if it hangs up or takes a long time i have no way to check what’s going on
looked up Popen after comments, now by doing
proc = subprocess.run(arguments , text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
i do get a separate window and stout/stderr but the new window has no text printed on it, likewise if i call Popen without redirecting stout and err to pipes
The subprocess module is a Python wrapper module for calling on Windows the Windows kernel library function CreateProcess with a STARTUPINFO structure.
shell=True
means callingCreateProcss
to run the executable defined by the environment variableComSpec
which is defined with%SystemRoot%\System32\cmd.exe
on Windows.The internal command START of the Windows Command Processor
cmd.exe
is for starting an executable for parallel execution tocmd.exe
by callingCreateProcess
bycmd.exe
for the executable to run. It can be seen here that the entire solution used by you does not make much sense. Why shouldpython.exe
callCreateProcess
to runcmd.exe
which is instructed to callCreateProcess
to run another executable? The executable to run parallel topython.exe
can be started directly withsubprocess.Popen()
for running parallel topython.exe
with a visible console window.It is even possible to define in the Python script on using
subprocess.Popen()
the parameters for the console window, i.e. the position on screen, the height and the width. That is all not possible on runningcmd.exe
for starting an executable using its internal commandstart
because of the commandstart
is very limited in its options for callingCreateProcess
in comparison tosubprocess.Popen()
. The solution for your XY problem is therefore going back a step, read the three referenced documentation pages, and rewrite the Python script code.BTW: What are the ERRORLEVEL values set by internal cmd.exe commands? explains what the internal command START of
cmd.exe
returns tocmd
assigned to its dynamic variableERRORLEVEL
of which value is returned on self-closing ofcmd.exe
to the parent process. The exit code is0
onstart
could successfully start the application, i.e.CreateProcess
returned a nonzero value (TRUE
).The application started with command START gets from
CreateProcess
its own standard input, standard output and standard error handles. The standard output and standard error ofcmd.exe
is for that reason always empty on successfully starting the executable. Standard error would be only not empty onCreateProcess
fails to find the executable to run as separate process (not fully detached but as child process in this case because of usingstart
option/w
). What you want to achieve is impossible as long as usingsubprocess.Run
withshell=True
and withcmd
internalstart
.Show 4 more comments