Módulo Subprocess de Python
Subprocess es un módulo incorporado que nos permite generar nuevos procesos del sistema, conectarnos a sus flujos de entrada/salida/error y obtener sus códigos de retorno.
import subprocess
Ejecutar un Comando del Sistema
La función run se utiliza para ejecutar un comando del sistema.
subprocess.run(['echo', 'Hello World!'])
Hello World!
Si desea ejecutar un comando como una sola cadena en lugar de una lista, use:
subprocess.run('echo Hello World!', shell=True)
Hello World!
Ambos imprimirán automáticamente la salida en la terminal.
ADVERTENCIA
Evite `shell=True` con entradas no confiables (riesgo de inyección de shell).
Capturar la Salida
Para capturar la salida, establezca capture_output en True:
result = subprocess.run(
['echo', 'Hello World!'],
capture_output=True,
text=True
)
output = result.stdout
error = result.stderr
returncode = result.returncode
output = "Hello World!\n"
error = ""
returncode = 0
Aquí, text=True le indica a la función que lea la salida como texto en lugar de bytes.
Un returncode de 0 indica éxito; cualquier valor distinto de cero indica un error.
Comprobar Errores
Si bien podemos verificar el éxito usando el código de retorno, hay una forma más “pythónica” de hacerlo:
try:
result = subprocess.run(
['ls', 'my_dir'],
check=True,
)
print('Finished without errors.')
except subprocess.CalledProcessError:
print('Error: Directory does not exist.')
Error: Directory does not exist.
Si check se establece en True y el código de retorno no es 0 (operación no exitosa), subprocess generará un subprocess.CalledProcessError, que se puede manejar de la manera habitual utilizando un bloque except.
Ejecutar Comandos con Tiempo de Espera (Timeout)
Puede establecer un tiempo de espera para un proceso. Si tarda más que el tiempo especificado, se genera subprocess.TimeoutExpired:
try:
subprocess.run(['sleep', '10'], timeout=5)
except subprocess.TimeoutExpired:
print('Process took too long!')
Process took too long!
Escribir Salida en un Archivo
Puede redirigir la salida a un archivo estableciendo stdout (y stderr, si es necesario) a un objeto de archivo:
with open('output.txt', 'w') as f:
subprocess.run(['ls', '-l'], stdout=f, stderr=f)
Aquí, tanto la salida normal como los errores aparecerán en el archivo, en el orden en que se generan.
Nota: text=True es útil cuando desea manipular la salida como una cadena en Python. No es estrictamente necesario cuando se redirige la salida directamente a un archivo.