子进程Popen和call之间的区别是什么(我该如何使用它们)?

var*_*unl 164 python subprocess popen

我想从Python调用外部程序.我已经使用了两者Popen()并且call()做到了这一点.

这两者有什么区别?

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

./my_script.sh > output
Run Code Online (Sandbox Code Playgroud)

我阅读了文档,它说这call()是一个便利功能或快捷功能.我们是否通过使用call()代替Popen()?而失去了任何力量?

agf*_*agf 245

有两种方法可以进行重定向.两者都适用于subprocess.Popensubprocess.call.

  1. 设置关键字参数shell = True或者executable = /path/to/the/shell像在那里一样指定命令.

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

    stdout = an_open_writeable_file_object
    
    Run Code Online (Sandbox Code Playgroud)

    对象指向output文件的位置.

subprocess.Popen比一般更普遍subprocess.call.

Popen不阻止,允许您在进程运行时与进程交互,或继续处理Python程序中的其他内容.调用Popen返回一个Popen对象.

call 确实块.虽然它支持所有与Popen构造函数相同的参数,因此您仍然可以设置进程的输出,环境变量等,您的脚本等待程序完成,并call返回表示进程退出状态的代码.

returncode = call(*args, **kwargs) 
Run Code Online (Sandbox Code Playgroud)

与呼叫基本相同

returncode = Popen(*args, **kwargs).wait()
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

如你所见,它是一个薄的包装Popen.

  • 基本上Popen和call是异步的,同步函数分别用于运行Linux命令. (17认同)
  • @Tom经常没有.如果你想读取一些输出,然后向程序发送更多输入,读取由该输入产生的更多输出,重复怎么办? (4认同)
  • 使用popen有什么好处?等待被调用的程序先完成不是安全吗? (2认同)

Bas*_*asj 35

另一个答案非常完整,但这里有一个经验法则:

  • 很好且易于理解的解释。谢谢你! (4认同)