Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a practical difference between check_call check_output call, and Popen methods in the subprocess module?

Honestly, I just don't understand the lingo of "non-zero" status to really interpret what's going on or what that means (it wasn't even defined) on help pages. What are some examples of using python to call other scripts in which these processes of

subprocess.call subprocess.check_output subprocess.popen

really differ from each other? When would you use either of those, and what are the disambiguated details of these methods? Should I be using os.system instead if I wanted simple OS calls?

like image 489
Tom Avatar asked Jun 29 '16 00:06

Tom


People also ask

What is difference between subprocess Popen and call?

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.

What is Popen in subprocess?

The subprocess module defines one class, Popen and a few wrapper functions that use that class. The constructor for Popen takes arguments to set up the new process so the parent can communicate with it via pipes. It provides all of the functionality of the other modules and functions it replaces, and more.

What is subprocess Check_output in Python?

The subprocess. check_output() is used to get the output of the calling program in python. It has 5 arguments; args, stdin, stderr, shell, universal_newlines. The args argument holds the commands that are to be passed as a string.

Should I use Popen or subprocess?

The Python documentation recommends the use of Popen in advanced cases, when other methods such like subprocess. call cannot fulfill our needs. This method allows for the execution of a program as a child process.


2 Answers

To expand on @otorrillas's answer with some examples.

Say you have a short script that you only care whether it succeeds or not*, and you just want to do it now and wait for the result. Say, for example, you want to send a single ping to a remote machine. call is the one for you:

res = call(['ping', '127.0.0.1', '-c', '1', '-W', '1'])
# res is 0 if the ping succeeded, non-zero if it failed. 

Now say that you have a command you want to assume is going to succeed, and is going to give you some output you want to use for something. check_output is for you. Perhaps a subversion command:

svn_output = check_output(['svn', 'info', path_to_my_working_copy])
# svn_output now contains the svn info output. If it failed, an 
# exception is thrown which more easily allows you to give 
# responsibility of that failure to whoever passed us the wrong 
# path_to_my_working_copy.

In general, if your use case does not simply fall under one of those categories, you are probably going to wind up using Popen.

One simple use case might be, say you have a daemon process that you want to start, but then run alongside of your python process. Now you use Popen:

my_proc = Popen(['my-daemon'])

# We're going to go and do something else now, but want to make sure
# my_proc dies when we do.
import atexit
atexit.register(my_proc.kill)

NB: If you use Popen raw, you must make sure you terminate the process, possibly using an atexit as I have illustrated.

* "non-zero" exit status just means the process failed. A famous computer science quote attributed to Tolstoy is "Happy processes are all alike; every unhappy process is unhappy in its own way", i.e. there's only one way for a process to be happy: to return 0. Everything else is unhappy, but there are lots of ways to be unhappy.

like image 44
daphtdazz Avatar answered Oct 02 '22 00:10

daphtdazz


The main difference is that, while popen is a non-blocking function (meaning you can continue the execution of the program without waiting the call to finish), both call and check_output are blocking.

The other difference is in what they return:

  • popen returns a Popen object.
  • call returns the returncode attribute.
  • check_output returns the output of the command execution.

The methods call and check_output are, in fact, blocking wrappers of popen, using a Popen object. For example, you can get the returncode attribute by calling Popen.returncode().

like image 96
otorrillas Avatar answered Oct 02 '22 01:10

otorrillas