【问题标题】:What is a practical difference between check_call check_output call, and Popen methods in the subprocess module?check_call check_output 调用和子流程模块中的 Popen 方法之间有什么实际区别?
【发布时间】:2016-10-31 12:20:26
【问题描述】:

老实说,我只是不理解“非零”状态的术语来真正解释帮助页面上发生的事情或这意味着什么(甚至没有定义)。有哪些使用python调用其他脚本的例子,其中这些进程的

subprocess.call subprocess.check_output subprocess.popen

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

【问题讨论】:

标签: python subprocess popen os.system


【解决方案1】:

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

另一个区别在于它们返回的内容:

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

【讨论】:

  • 值得一提的是,现在所有阻塞的事情都应该使用 subprocess.run 来完成
【解决方案2】:

用一些例子来扩展@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)

注意:如果您使用Popen raw,您必须确保终止进程,可能使用atexit,如我所说明的。

* “非零”退出状态仅表示进程失败。归因于Tolstoy 的一句著名的计算机科学名言是“快乐的过程都是相似的;每个不快乐的过程都以自己的方式不快乐”,即一个过程只有一种快乐的方式:返回 0。其他一切都不快乐,但是不开心的方式有很多。

【讨论】:

  • 您可能是指第二个示例中的 call_output 吗? check_call 不提供输出,我相信只返回代码。
  • 感谢@taiko 我已经解决了!虽然我认为正确的功能是 check_output 而不是 call_output。令人惊讶的是,有人花了两年时间才发现它:-)
  • 值得一提的是,现在所有阻塞的事情都应该使用 subprocess.run 来完成
  • 嗨@daphtdazz 我不认为check_output 适合与joblib.Parallel 一起使用,因为所有线程都会继续等待直到超时,即使它们已经完成。
猜你喜欢
  • 2017-05-28
  • 2018-04-16
  • 1970-01-01
  • 2016-11-19
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
相关资源
最近更新 更多