¿Cuál es la diferencia entre el subproceso Popen y la llamada (cómo puedo usarlos)?
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()
?
Hay dos formas de realizar la redirección. Ambos se aplican a cualquiera subprocess.Popen
o subprocess.call
.
Establezca el argumento de palabra clave
shell = True
oexecutable = /path/to/the/shell
y especifique el comando tal como lo tiene allí.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
output
archivo.
subprocess.Popen
es más general que subprocess.call
.
Popen
no 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 Popen
devuelve un Popen
objeto.
call
bloquea . Si bien admite los mismos argumentos que el Popen
constructor, 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 call
devuelve 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()
call
Es 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
.
La otra respuesta es muy completa, pero aquí tienes una regla general:
call
está bloqueando:call('notepad.exe') print('hello') # only executed when notepad is closed
Popen
no es bloqueante:Popen('notepad.exe') print('hello') # immediately executed