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

时间:2015-08-14 20:01:31

标签: python scripting sysadmin

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

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

我阅读了关于子进程的文档,看看call()基本上做了同样的事情。在不记得当天发生的事情的情况下,除了上面的func和subprocess.call([“mycommand”])之外,任何python系统管理员都知道使用中有意义的差异吗?我看到我的func没有返回任何退出状态,正在检查命令是否对call()有唯一的区别/优势?这就是我今天看到的

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

感谢

2 个答案:

答案 0 :(得分:2)

如果您重定向子进程的任何标准流,例如subprocess.call(..)或者您需要退出状态,则

Popen(..).wait()基本上Popen(..).communicate()stdout=PIPE不同。

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

编写一个方便的功能,就像你一样在你的情况下工作是一个好主意(尽管你的特定例子不太有用)。 Popen()可以执行许多操作,并且限制其功能的便利功能使代码更易于维护。

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

答案 1 :(得分:1)

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

如果需要与正在运行的子进程交换某些数据,或者为了进一步处理命令输出(stdout,stderr),Popencommunicate会更合适。

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