Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blocking and Non Blocking subprocess calls

I'm completely confused between subprocess.call() , subprocess.Popen(), subprocess.check_call().

Which is blocking and which is not ?

What I mean to say is if I use subprocess.Popen() whether the parent process waits for the child process to return/exit before it keep on its execution.

How does shell=True affect these calls?

like image 749
Roshan Mehta Avatar asked Feb 21 '14 14:02

Roshan Mehta


People also ask

Is Popen blocking call?

Popen is nonblocking. call and check_call are blocking. You can make the Popen instance block by calling its wait or communicate method.

What is the difference between subprocess call and Popen?

Popen is more general than subprocess. call . Popen doesn't block, allowing you to interact with the process while it's running, or continue with other things in your Python program. The call to Popen returns a Popen object.

Does subprocess call raise exception?

check_call will raise an exception if the command it's running exits with anything other than 0 as its status.


1 Answers

Popen is nonblocking. call and check_call are blocking. You can make the Popen instance block by calling its wait or communicate method.

If you look in the source code, you'll see call calls Popen(...).wait(), which is why it is blocking. check_call calls call, which is why it blocks as well.

Strictly speaking, shell=True is orthogonal to the issue of blocking. However, shell=True causes Python to exec a shell and then run the command in the shell. If you use a blocking call, the call will return when the shell finishes. Since the shell may spawn a subprocess to run the command, the shell may finish before the spawned subprocess. For example,

import subprocess import time  proc = subprocess.Popen('ls -lRa /', shell=True) time.sleep(3) proc.terminate() proc.wait() 

Here two processes are spawned: Popen spawns one subprocess running the shell. The shell in turn spawns a subprocess running ls. proc.terminate() kills the shell, but the subprocess running ls remains. (That is manifested by copious output, even after the python script has ended. Be prepared to kill the ls with pkill ls.)

like image 164
unutbu Avatar answered Sep 20 '22 13:09

unutbu