check_call check_output调用和子进程模块中的Popen方法有什么实际区别?

时间:2016-06-29 00:59:57

标签: python subprocess popen os.system

老实说,我只是不理解“非零”状态的术语来真正解释在帮助页面上发生了什么或者意味着什么(甚至没有定义)。有哪些使用python调用

这些进程的脚本的例子

subprocess.call subprocess.check_output subprocess.popen

彼此真的不一样吗? 你何时会使用其中任何一种,以及这些方法的消歧细节是什么?如果我想要简单的操作系统调用,我应该使用os.system吗?

2 个答案:

答案 0 :(得分:9)

主要区别在于,虽然popen非阻塞函数(意味着您可以继续执行程序而无需等待调用完成),但{{3} }和call 阻止

另一个区别在于他们的回报:

方法check_outputcall实际上是使用Popen object 阻止 check_output的包装。 例如,您可以通过调用Popen.returncode()来获取popen属性。

答案 1 :(得分:8)

通过一些例子扩展@ otorrillas的答案。

假设你有一个简短的脚本,你只关心它是否成功*,你只想现在就做,等待结果。例如,假设您要将一个ping发送到远程计算机。 call是适合你的人:

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

现在说你有一个你想要假设成功的命令,并且会给你一些你想用来做某事的输出。 check_output适合你。也许是一个颠覆命令:

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.

一般情况下,如果您的用例不仅仅属于其中一个类别,那么您最终可能会使用Popen

一个简单的用例可能是,你有一个你想要启动的守护进程,但随后会运行你的python进程。现在使用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:如果您使用Popen raw,则必须确保终止此过程,可能使用我所说明的atexit

*"非零"退出状态只表示流程失败。归因于Tolstoy的着名计算机科学报价是"快乐的过程都是相似的;每个不愉快的过程都以自己的方式不开心,即只有一种方法让一个过程变得快乐:返回0.其他一切都不快乐,但有很多方法可以不快乐。