Módulo Python subprocess
subprocessEs un módulo de la biblioteca estándar de Python, utilizado para crear y gestionar subprocesos.
subprocessTe permite ejecutar comandos externos en programas Python e interactuar con estos comandos.
A través del módulosubprocess, puedes ejecutar comandos del sistema, llamar a otros programas y obtener su salida o información de error.
¿Por qué usar el módulo subprocess?
En Python, a veces necesitamos ejecutar algunos comandos del sistema o llamar a otros programas para completar tareas específicas. Por ejemplo, es posible que necesites ejecutar un comando de shell, iniciar una aplicación externa o interactuar con una herramienta de línea de comandos.subprocessEl módulo proporciona una forma segura y flexible de manejar estas necesidades.
En comparación con los primerosos.system()oos.popen()en comparación,subprocessEl módulo proporciona funciones más potentes y una mejor capacidad de control. Te permite gestionar con mayor precisión los flujos de entrada, salida y error de los subprocesos, y puede manejar escenarios más complejos.
Funciones principales del módulo subprocess
1. Ejecutar comandos externos
subprocess.run()SísubprocessUna de las funciones más utilizadas del módulo. Puede ejecutar un comando externo y esperar a que el comando termine. A continuación se muestra un ejemplo sencillo:
Ejemplo
# Ejecutar un comando simple de shell
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
# Imprimir la salida del comando
print(result.stdout)
En este ejemplo,subprocess.run()ejecutó el comandols -l, y capturó la salida enresult.stdout.
2. Manejar la entrada y la salida
subprocessEl módulo te permite controlar los flujos de entrada, salida y error del subproceso. Puedes pasar datos a la entrada estándar del subproceso, o leer datos de la salida estándar y del error estándar del subproceso. A continuación se muestra un ejemplo:
Ejemplo
# Ejecutar un comando y pasar la entrada al subproceso
result = subprocess.run(['grep', 'python'], input='hello\npython\nworld', capture_output=True, text=True)
# Imprimir la salida del comando
print(result.stdout)
En este ejemplo,subprocess.run()ejecutó el comandogrep python, y pasó la cadena'hello\npython\nworld'como entrada al subproceso.
3. Manejar errores
subprocessEl módulo también te permite manejar los errores del subproceso. Si el subproceso devuelve un código de estado de salida distinto de cero,subprocess.run()lanzará unaCalledProcessErrorexcepción. Puedes comprobarresult.returncodepara obtener el código de estado de salida del subproceso.
Ejemplo
try:
result = subprocess.run(['ls', 'nonexistent_file'], capture_output=True, text=True, check=True)
except subprocess.CalledProcessError as e:
print(f"Command failed with return code {e.returncode}")
print(f"Error output: {e.stderr}")
En este ejemplo,subprocess.run()ejecutó el comandols nonexistent_file, y debido a que el archivo no existe, el comando falló y se lanzó unaCalledProcessErrorexcepción.
Uso avanzado del módulo subprocess
1. Usar la clase Popen
subprocess.PopenLa clase proporciona una interfaz de más bajo nivel, lo que te permite controlar el subproceso de forma más flexible. Puedes usarPopenpara iniciar un subproceso, ejecutarlo en segundo plano o interactuar con él.
Ejemplo
# Iniciar un subproceso
process = subprocess.Popen(['ping', 'google.com'], stdout=subprocess.PIPE, text=True)
# Leer la salida del subproceso
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
# Obtener el código de estado de salida del subproceso
return_code = process.poll()
print(f"Process finished with return code {return_code}")
En este ejemplo,subprocess.Popeninició un comandoping google.com, y lo ejecutó en segundo plano. El programa lee la salida del subproceso mediante un bucle, y obtiene su código de estado de salida cuando el subproceso finaliza.
2. Usar tuberías (pipes)
subprocessEl módulo te permite usar tuberías (pipes) para conectar varios comandos entre sí. Puedes usar la salida de un comando como entrada de otro comando.
Ejemplo
# Usar una tubería (pipe) para conectar dos comandos
p1 = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'py'], stdin=p1.stdout, stdout=subprocess.PIPE, text=True)
# Obtener la salida final
output = p2.communicate()[0]
print(output)
En este ejemplo,ls -lla salida del comando se pasa algrep py, y la salida final contienepylos archivos o directorios.
Métodos, clases y parámetros comunes del módulo subprocess
A continuación se muestra la explicación de los métodos, clases y parámetros comunes del módulo subprocess de Python, incluyendo la descripción de funcionalidades y ejemplos:
Métodos principales del módulo subprocess
| Método | Descripción | Ejemplo |
|---|---|---|
subprocess.run() | Ejecuta un comando y espera a que termine (recomendado) | subprocess.run(["ls", "-l"], capture_output=True, text=True) |
subprocess.Popen() | Crea un subproceso (control de bajo nivel) | proc = subprocess.Popen(["ping", "google.com"], stdout=subprocess.PIPE) |
subprocess.call() | Ejecuta un comando y devuelve el código de salida (versión antigua) | exit_code = subprocess.call(["python", "--version"]) |
subprocess.check_call() | Ejecuta un comando, y lanza una excepción si falla | subprocess.check_call(["git", "commit"]) |
subprocess.check_output() | Ejecuta un comando y devuelve la salida (versión antigua) | output = subprocess.check_output(["date"], text=True) |
Atributos del objeto subprocess.CompletedProcess (objeto devuelto por el método run())
| Atributo | Descripción |
|---|---|
args | Lista de argumentos del comando ejecutado |
returncode | Código de estado de salida del proceso (0 indica éxito) |
stdout | Contenido de la salida estándar (si se configurócapture_output) |
stderr | Contenido del error estándar (si se configurócapture_output) |
Métodos/atributos comunes de la clase subprocess.Popen
| Método/Atributo | Descripción | Ejemplo |
|---|---|---|
poll() | Comprueba si el proceso ha terminado (devuelveNoneindicando si está en ejecución) | if proc.poll() is None: print("Running") |
wait() | Espera bloqueante hasta que el proceso termine | proc.wait() |
communicate() | Entrada/salida interactiva | stdout, stderr = proc.communicate(input="data") |
terminate() | Envía la señal de terminación (SIGTERM) | proc.terminate() |
kill() | Fuerza la terminación del proceso (SIGKILL) | proc.kill() |
stdin | Flujo de entrada estándar del proceso | proc.stdin.write("input") |
stdout | Flujo de salida estándar del proceso | print(proc.stdout.read()) |
stderr | Flujo de error estándar del proceso | errors = proc.stderr.read() |
Explicación de parámetros comunes (aplicable a run() y Popen())
| Parámetro | Descripción | Valor de ejemplo |
|---|---|---|
args | Comando (lista o cadena) | ["ls", "-l"]o"ls -l" |
stdin | Configuración de la entrada estándar | subprocess.PIPE(tubería),None(heredar) |
stdout | Configuración de la salida estándar | subprocess.PIPE、open('log.txt', 'w') |
stderr | Configuración del error estándar | subprocess.STDOUT(fusionar a stdout) |
shell | Si se ejecuta a través de Shell | True(admite comandos de cadena) |
cwd | Ruta del directorio de trabajo | "/tmp" |
env | Variables de entorno personalizadas | {"PATH": "/usr/bin"} |
timeout | Tiempo de espera (segundos) | 30 |
text | Si la entrada/salida es una cadena (no bytes) | True |
Ejemplo
Ejecutar un comando y capturar la salida:
Ejemplo
print(result.stdout) # Salida: "Hello\n"
Ejecutar comandos complejos a través de Shell:
subprocess.run("grep 'error' log.txt | wc -l", shell=True, check=True)Obtener el flujo de salida en tiempo real:Ejemplo
while True:
line = proc.stdout.readline()
if not line: break
print(line.decode().strip())
Control de tiempo de espera:
Ejemplo
subprocess.run(["sleep", "10"], timeout=5)
except subprocess.TimeoutExpired:
print("¡El comando agotó el tiempo de espera!")