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

心不动则不痛 提交于 2020-07-17 01:41:14

问题


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?


回答1:


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().




回答2:


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.



来源:https://stackoverflow.com/questions/38088631/what-is-a-practical-difference-between-check-call-check-output-call-and-popen-m

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!