sp = subprocess.Popen() 的优点 --> sp.communicate() 对比 subprocess.call()

advantages of sp = subprocess.Popen() --> sp.communicate() vs subprocess.call()

大约 4 个月前我写了一个我经常使用的函数,但我很难记住为什么要这样拆分:

def call_sp(command, **arg_list):
    #run that beast
    p = subprocess.Popen(command, shell=True, **arg_list)
    p.communicate()

我阅读了关于子进程的文档,发现 call() 基本上做同样的事情。在不记得那天发生的事情的情况下,任何 python 系统管理员是否知道除了上述 func 和 subprocess.call(["mycommand"]) 在使用上的一个有意义的区别?我看到我的 func 没有 return 任何退出状态,正在检查命令是否只对 call() 有效 difference/advantage?这是我今天看到的

In [4]: subprocess.call(['echo $HOME'], shell=True)
/home/cchilders
Out[4]: 0

In [5]: %paste
def call_sp(command, **arg_list):
    #run that beast
    p = subprocess.Popen(command, shell=True, **arg_list)
    p.communicate()

## -- End pasted text --


In [6]: call_sp('echo $HOME')
/home/cchilders

谢谢

callPopen 典型用例的便利函数。在这种情况下,使用它而不是 Popen 构造函数更简单,因为您没有使用已执行命令的输出。

如果需要与 运行 子进程交换一些数据或进一步处理命令输出 (stdout, stderr) Popencommunicate 将是更合身。

如果您对调用的成功感兴趣,还有另一个方便的函数 check_call 如果执行的进程以非零状态退出,它将引发异常。

subprocess.call(..) 本质上是 Popen(..).wait()Popen(..).communicate() 不同,如果您重定向子进程的任何标准流,例如 stdout=PIPE 或者如果您需要退出状态。

subprocess.call() 是建立在 Popen() 提供的接口之上的便利函数。如果 call() 适用于您的情况;用它。如果它不起作用;考虑其他便利功能,例如 subprocess.check_output(),然后才直接使用 Popen()

编写一个像您所做的那样适用于您的情况的便利函数通常是一个好主意(尽管您的特定示例不太有用)。 Popen() 可以做很多事情,限制其功能的便捷功能使代码更易于维护。

除非您需要传递输入,否则不要调用 p.communicate(),从子进程获取输出。不要使用 shell=True 除非您 完全 控制 command 参数。