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

import subprocess

# 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

import subprocess

# 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

import subprocess

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

import subprocess

# 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

import subprocess

# 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étodoDescripciónEjemplo
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 fallasubprocess.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())

AtributoDescripción
argsLista de argumentos del comando ejecutado
returncodeCódigo de estado de salida del proceso (0 indica éxito)
stdoutContenido de la salida estándar (si se configurócapture_output)
stderrContenido del error estándar (si se configurócapture_output)

Métodos/atributos comunes de la clase subprocess.Popen

Método/AtributoDescripciónEjemplo
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 termineproc.wait()
communicate()Entrada/salida interactivastdout, 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()
stdinFlujo de entrada estándar del procesoproc.stdin.write("input")
stdoutFlujo de salida estándar del procesoprint(proc.stdout.read())
stderrFlujo de error estándar del procesoerrors = proc.stderr.read()

Explicación de parámetros comunes (aplicable a run() y Popen())

ParámetroDescripciónValor de ejemplo
argsComando (lista o cadena)["ls", "-l"]o"ls -l"
stdinConfiguración de la entrada estándarsubprocess.PIPE(tubería),None(heredar)
stdoutConfiguración de la salida estándarsubprocess.PIPE、open('log.txt', 'w')
stderrConfiguración del error estándarsubprocess.STDOUT(fusionar a stdout)
shellSi se ejecuta a través de ShellTrue(admite comandos de cadena)
cwdRuta del directorio de trabajo"/tmp"
envVariables de entorno personalizadas{"PATH": "/usr/bin"}
timeoutTiempo de espera (segundos)30
textSi la entrada/salida es una cadena (no bytes)True

Ejemplo

Ejecutar un comando y capturar la salida:

Ejemplo

result = subprocess.run(["echo", "Hello"], capture_output=True, text=True)
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

proc = subprocess.Popen(["tail", "-f", "log.txt"], stdout=subprocess.PIPE)
while True:
    line = proc.stdout.readline()
    if not line: break
    print(line.decode().strip())

Control de tiempo de espera:

Ejemplo

try:
    subprocess.run(["sleep", "10"], timeout=5)
except subprocess.TimeoutExpired:
    print("¡El comando agotó el tiempo de espera!")
Otras extensiones