子进程 Popen 和 call 有啥区别(我该如何使用它们)?
Posted
技术标签:
【中文标题】子进程 Popen 和 call 有啥区别(我该如何使用它们)?【英文标题】:What's the difference between subprocess Popen and call (how can I use them)?子进程 Popen 和 call 有什么区别(我该如何使用它们)? 【发布时间】:2011-12-02 15:52:34 【问题描述】:我想从 Python 调用一个外部程序。我已经使用 Popen()
和 call()
来做到这一点。
两者有什么区别?
我的具体目标是从 Python 运行以下命令。我不确定重定向是如何工作的。
./my_script.sh > output
我读过the documentation,它说call()
是一个便利功能或快捷功能。使用call()
而不是Popen()
,我们会失去任何权力吗?
【问题讨论】:
文档的哪一部分让您感到困惑?call()
的定义似乎很明确。您能否提供报价或链接,以便我们知道在回答中重点关注什么?
【参考方案1】:
有两种方法可以进行重定向。两者都适用于subprocess.Popen
或subprocess.call
。
设置关键字参数shell = True
或executable = /path/to/the/shell
并指定命令,就像你在那里一样。
由于您只是将输出重定向到文件,因此请设置关键字参数
stdout = an_open_writeable_file_object
对象指向output
文件的位置。
subprocess.Popen
比 subprocess.call
更通用。
Popen
不会阻塞,允许您在进程运行时与其进行交互,或继续在 Python 程序中进行其他操作。对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
周围的薄包装。
【讨论】:
Popen 和 call 基本上是异步和同步函数,分别用于运行 Linux 命令。 使用popen有什么好处?等到被调用的程序先完成不安全吗? @Tom 通常不会。如果你想读取一些输出,然后向程序发送更多输入,读取更多由该输入产生的输出,重复? @user3016020 我认为这也适用于 Windows 命令?对吗? 我认为 popen 有一个可迭代的参数,而调用一个字符串。【参考方案2】:另一个答案很完整,但这里有一个经验法则:
call
正在阻塞:
call('notepad.exe')
print('hello') # only executed when notepad is closed
Popen
是非阻塞的:
Popen('notepad.exe')
print('hello') # immediately executed
【讨论】:
以上是关于子进程 Popen 和 call 有啥区别(我该如何使用它们)?的主要内容,如果未能解决你的问题,请参考以下文章
subprocess.call() 和 subprocess.Popen() 之间有啥区别使 PIPE 对前者的安全性降低?