子流程Popen和call有什么区别(我该如何使用它们)?


177

我想从Python调用一个外部程序。我已经使用过Popen()并且call()做到了。

两者有什么区别?

我的特定目标是从Python运行以下命令。我不确定重定向如何工作。

./my_script.sh > output

我阅读了文档,并说它call()是便利功能或快捷功能。我们使用call()代替会失去任何功能Popen()吗?


文档的哪一部分让您感到困惑?的定义call()似乎非常清楚。您能否提供报价或链接,以便我们知道答案中的重点?
S.Lott

Answers:


262

重定向有两种方法。两者都适用于subprocess.Popensubprocess.call

  1. 设置关键字参数shell = Trueexecutable = /path/to/the/shell并在那里指定命令。

  2. 由于您只是将输出重定向到文件,因此请设置关键字参数

    stdout = an_open_writeable_file_object

    对象指向output文件的位置。

subprocess.Popensubprocess.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


17
基本上,Popen和call是分别用于运行Linux命令的异步和同步函数。
user3016020 2015年

1
使用popen有什么好处?等到被调用程序首先完成不是安全的吗?
汤姆(Tom)

4
@汤姆经常不。如果您想读取一些输出,然后将更多的输入发送到程序,读取该输入产生的更多输出,重复该怎么办?
2016年

@ user3016020我认为这也适用于Windows命令吗?对?
domih

7

另一个答案很完整,但这是一个经验法则:

  • call 正在阻止:

    call('notepad.exe')
    print('hello')  # only executed when notepad is closed
    
  • Popen 是非阻塞的:

    Popen('notepad.exe')
    print('hello')  # immediately executed
    
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.