39

I don't understand why it's so hard to do this on Windows.

I want to spawn a bunch of command prompt windows which will run other scripts. The reason I want this is so I can see all the output from each script neatly (if I have them just be threads/subprocesses in the main window I can't view all the output properly). I also don't want to log the output because it's mostly for viewing progress bars, which don't really work with log files.

So individual parts of my requirements work, but not together:

os.system("start cmd /c {command here}")     # Launches in new command prompt, closes when done

However, os system won't let me wait until the command finishes (since start is the actual command, the second it opens the new command prompt it's "done")

Similarly if I try:

p = subprocess.Popen(["start", "cmd", "/k", "{command here}"], shell = True) # Needs to be shell since start isn't an executable, its a shell cmd
p.wait()    # I can wait until finished (although it too finishes after start finishes)

So how do I do this? I read somewhere that a solution could be to use processgroup but it's unix only....or something like that

Or if you have a neat way of displaying the output from all the subprocesses in a single window, then I don't need to open a new command prompt and can simply use threads. That works too, but if I have lets say 4 threads downloading something and displaying a progress bar as well as outputting other information I don't know how to display that in a way that can be read (as well as avoiding them all colliding with each other).

PS: This is on Windows Vista. PPS: I'd preferably like a solution that works on Windows, Linux and Mac, I'm focusing on Windows for now but I'd like a solution that works for all three, and I know Windows is the most finicky. I would just substitute "the start cmd /c" for the OS appropriate command.

0

6 Answers 6

54

Upon reading your comment to my previous answer what you need is:

os.system("start /wait cmd /c {command}")

Keep the windows command reference always at hand!

Sign up to request clarification or add additional context in comments.

4 Comments

/c just closes the cmd without even waiting for the command to complete execution. Is there a way for it to wait until the command is executed completely and then close the command prompt automatically? Or if any other way to run multiple commands on the new cmd window?
No. From the windows command reference linked in the answer: /c Carries out the command specified by String and then stops.
Note, that if command needs to be multiple commands, && must be escaped with ^ e.g. echo hello ^&^& cd x ^&^& dir See: stackoverflow.com/questions/34698230/…
Run cmd /? to check the help instead of trusting answers you find online: /C Carries out the command specified by string and then terminates. (The docs say the same.) You can remember that /c is for close and /k is for keep.
26

The accepted answer didn't work for me.
To open on a new command prompt I had to use:

os.system("start /B start cmd.exe @cmd /k mycommand...")

2 Comments

That's not true. /B make sure you do NOT open a command prompt
@yes4me, you may be right, but oddly enough, this code starts a new command prompt on Windows and wait for it finish/exit, go figure...
16

For me this seems to work
os.system("cmd /k {command}")

With /k cmd executes and then remain open
With /c executes and close

To open a new command window and then execute the command
os.system("start cmd /k {command}")

Comments

4

You can pass /WAIT to the start command to make it wait for termination.

Comments

2

How about

os.system("cmd /c {command here}") 

Or even

os.system("{command here}")

It is the start command the one that is launching a separate session instead of using the same one the python program is running on.

2 Comments

That doesn't start a new command prompt window, it runs it in the current window
A bit annoying the SO shows this answer over the correct one with 52 upvotes, compared to this with 2. Sorry, but have to downvote.
2

The simplest way (as pointed out) to open a new cmd-window is to use:

os.system("start /wait cmd /k {command}")

but it's not very useful if your command is a complex one with spaces or other control characters. For that I use:

subprocess.run(["start", "/wait", "cmd", "/K", command, "arg /?\^"], shell=True)

1 Comment

That shell=True is key to use with subprocess. Thanks for the subprocess answer!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.