¿Cuál es la diferencia entre el subproceso Popen y la llamada (cómo puedo usarlos)?

Resuelto varunl asked hace 12 años • 2 respuestas

Quiero llamar a un programa externo desde Python. He usado ambos Popen()y call()para hacer eso.

¿Cuál es la diferencia entre los dos?

Mi objetivo específico es ejecutar el siguiente comando desde Python. No estoy seguro de cómo funcionan las redirecciones.

./my_script.sh > output

Leí la documentación y dice que call()es una función de conveniencia o una función de acceso directo. ¿Perdemos poder al usar call()en lugar de Popen()?

varunl avatar Oct 07 '11 06:10 varunl
Aceptado

Hay dos formas de realizar la redirección. Ambos se aplican a cualquiera subprocess.Popeno subprocess.call.

  1. Establezca el argumento de palabra clave shell = Trueo executable = /path/to/the/shelly especifique el comando tal como lo tiene allí.

  2. Dado que solo estás redirigiendo la salida a un archivo, configura el argumento de palabra clave

    stdout = an_open_writeable_file_object
    

    donde el objeto apunta al outputarchivo.

subprocess.Popenes más general que subprocess.call.

Popenno se bloquea, lo que le permite interactuar con el proceso mientras se ejecuta o continuar con otras cosas en su programa Python. La llamada a Popendevuelve un Popenobjeto.

call bloquea . Si bien admite los mismos argumentos que el Popenconstructor, por lo que aún puede configurar la salida del proceso, las variables ambientales, etc., su script espera a que se complete el programa y calldevuelve un código que representa el estado de salida del proceso.

returncode = call(*args, **kwargs) 

es básicamente lo mismo que llamar

returncode = Popen(*args, **kwargs).wait()

callEs solo una función de conveniencia. Su implementación en CPython está en 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

Como puede ver, es una envoltura delgada Popen.

agf avatar Oct 06 '2011 23:10 agf

La otra respuesta es muy completa, pero aquí tienes una regla general:

  • callestá bloqueando:

    call('notepad.exe')
    print('hello')  # only executed when notepad is closed
    
  • Popenno es bloqueante:

    Popen('notepad.exe')
    print('hello')  # immediately executed
    
Basj avatar Jan 06 '2020 16:01 Basj