subprocess的Popen和call有什么区别(我该如何使用它们)?
我想从Python中调用一个外部程序。我用过 Popen()
和 call()
这两个方法。
这两者有什么区别呢?
我具体想要做的是从Python运行以下命令。我对重定向是怎么回事还不太明白。
./my_script.sh > output
我看了文档,上面说 call()
是一个方便的函数,或者说是一个快捷函数。那用 call()
代替 Popen()
会失去什么功能吗?
2 个回答
61
另一个回答很全面,但这里有个简单的原则:
call
是阻塞的:call('notepad.exe') print('hello') # only executed when notepad is closed
Popen
是非阻塞的:Popen('notepad.exe') print('hello') # immediately executed
321
重定向有两种方法。这两种方法都适用于 subprocess.Popen
或 subprocess.call
。
设置关键字参数
shell = True
或executable = /path/to/the/shell
,然后像你写的那样指定命令。因为你只是把输出重定向到一个文件,所以设置关键字参数
stdout = an_open_writeable_file_object
这里的对象指向
output
文件。
subprocess.Popen
比 subprocess.call
更通用。
Popen
不会阻塞,这意味着你可以在它运行的时候与这个进程互动,或者继续做其他事情。调用 Popen
会返回一个 Popen
对象。
call
是会阻塞的。虽然它支持与 Popen
构造函数相同的所有参数,所以你仍然可以设置进程的输出、环境变量等等,但你的脚本会等待程序完成,然后 call
会返回一个表示进程退出状态的代码。
returncode = call(*args, **kwargs)
基本上和调用
returncode = Popen(*args, **kwargs).wait()
call
只是一个方便的函数。它在 CPython 中的实现可以在 subprocess.py 找到:
def call(*popenargs, timeout=None, **kwargs):
"""Run command with arguments. Wait for command to complete or
timeout, then return the returncode attribute.
The arguments are the same as for the Popen constructor. Example:
retcode = call(["ls", "-l"])
"""
with Popen(*popenargs, **kwargs) as p:
try:
return p.wait(timeout=timeout)
except:
p.kill()
p.wait()
raise
如你所见,它只是对 Popen
的一个简单封装。