Subprocess en Python: ejecutar comandos del terminal

Publicado el: 11/07/2026
Tempo de leitura: 4 minutos
Execução de comandos do terminal usando Python

El módulo subprocess en Python permite ejecutar programas externos y comandos del sistema desde un script. Es útil para automatizar herramientas, consultar versiones, comprimir archivos, ejecutar pruebas, invocar Git o conectar varias etapas de un flujo de trabajo.

La función recomendada para la mayoría de los casos es subprocess.run(). Ofrece control sobre argumentos, salida, errores, códigos de retorno, tiempo máximo y variables de entorno. Esta guía muestra cómo utilizarla de forma segura y portable.

Ejecutar el primer comando

import subprocess

result = subprocess.run(
    ["python", "--version"],
    check=True,
)

print(result.returncode)

Los argumentos se pasan como una lista. Cada elemento representa una parte del comando. Este formato evita problemas de espacios y reduce riesgos relacionados con la interpretación de texto por una shell.

La documentación oficial de subprocess recomienda run() para los casos que no necesitan una interacción avanzada con el proceso.

Capturar la salida estándar

import subprocess

result = subprocess.run(
    ["python", "--version"],
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout.strip())
print(result.stderr.strip())

capture_output=True conserva stdout y stderr. text=True convierte bytes en strings. Sin esa opción, el resultado se recibe como bytes.

La guía de strings en Python explica limpieza, codificación y transformación de texto.

Comprobar errores con check=True

Un comando puede terminar con un código diferente de cero. Sin check=True, Python devuelve el resultado y deja la validación al programa:

import subprocess

try:
    result = subprocess.run(
        ["python", "missing_script.py"],
        capture_output=True,
        text=True,
        check=True,
    )
except subprocess.CalledProcessError as error:
    print("El comando falló")
    print(error.returncode)
    print(error.stderr)

La guía de try y except en Python explica cómo capturar excepciones específicas y conservar el contexto.

Establecer un tiempo máximo

import subprocess

try:
    subprocess.run(
        ["python", "slow_task.py"],
        timeout=10,
        check=True,
    )
except subprocess.TimeoutExpired:
    print("El proceso superó el límite")

Un timeout evita que una automatización quede bloqueada indefinidamente. El valor correcto depende de la tarea y del entorno.

Evitar shell=True cuando no sea necesario

El argumento shell=True envía una cadena a la shell del sistema. Puede ser necesario para pipes, redirecciones o comandos internos, pero aumenta el riesgo cuando el texto contiene datos externos:

# Evita construir comandos con entrada del usuario
subprocess.run(
    f"tool --file {user_value}",
    shell=True,
)

Prefiere una lista:

subprocess.run(
    ["tool", "--file", user_value],
    check=True,
)

La sección de consideraciones de seguridad de subprocess explica la responsabilidad del desarrollador cuando utiliza una shell.

Ejecutar comandos diferentes según el sistema

import platform
import subprocess

system = platform.system()

if system == "Windows":
    command = ["cmd", "/c", "dir"]
else:
    command = ["ls", "-la"]

result = subprocess.run(
    command,
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout)

Cuando la tarea puede resolverse con la biblioteca estándar, una solución nativa suele ser más portable. Para archivos, consulta pathlib en Python y el módulo os.

Definir el directorio de trabajo

from pathlib import Path
import subprocess

project = Path.home() / "projects" / "demo"

result = subprocess.run(
    ["git", "status", "--short"],
    cwd=project,
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout)

cwd evita depender del directorio desde el que se inició el script.

Pasar variables de entorno

import os
import subprocess

environment = os.environ.copy()
environment["APP_MODE"] = "test"

subprocess.run(
    ["python", "app.py"],
    env=environment,
    check=True,
)

No reemplaces todo el entorno con un diccionario pequeño, porque el proceso puede necesitar PATH y otras variables. Tampoco incluyas secretos en mensajes de error o logs.

Enviar datos a stdin

import subprocess

result = subprocess.run(
    ["python", "processor.py"],
    input="first line\nsecond line\n",
    capture_output=True,
    text=True,
    check=True,
)

print(result.stdout)

input permite alimentar un proceso sin crear un archivo temporal.

Ejecutar una herramienta y convertir su salida

import json
import subprocess

result = subprocess.run(
    ["tool", "--format", "json"],
    capture_output=True,
    text=True,
    check=True,
)

data = json.loads(result.stdout)
print(data)

Valida siempre que la salida exista y tenga el formato esperado. Un proceso puede escribir mensajes de diagnóstico en stdout o stderr según su diseño.

Construir una función reutilizable

import subprocess


def run_command(command, *, cwd=None, timeout=30):
    try:
        return subprocess.run(
            command,
            cwd=cwd,
            timeout=timeout,
            capture_output=True,
            text=True,
            check=True,
        )
    except FileNotFoundError as error:
        raise RuntimeError(
            f"No se encontró el programa: {command[0]}"
        ) from error
    except subprocess.TimeoutExpired as error:
        raise RuntimeError(
            "El comando superó el tiempo máximo"
        ) from error
    except subprocess.CalledProcessError as error:
        message = error.stderr.strip() or "Sin detalles"
        raise RuntimeError(
            f"El comando falló: {message}"
        ) from error

La guía de funciones en Python ayuda a diseñar interfaces pequeñas y comprobables.

Crear una interfaz con argparse

Un script de automatización puede recibir parámetros y después ejecutar otra herramienta:

import argparse
import subprocess

parser = argparse.ArgumentParser()
parser.add_argument("filename")
args = parser.parse_args()

subprocess.run(
    ["python", "validator.py", args.filename],
    check=True,
)

La guía de argparse en Python explica opciones, tipos, ayuda y subcomandos.

Cuándo utilizar Popen

subprocess.Popen ofrece control de bajo nivel para procesos que deben continuar activos, intercambiar datos progresivamente o ejecutarse en paralelo. Para un comando que comienza, termina y devuelve un resultado, run() suele ser más claro.

Registrar sin exponer datos

import logging

logger = logging.getLogger(__name__)
logger.info("Ejecutando validación de archivos")

Registra la operación general, duración y código de salida. Evita tokens, contraseñas, argumentos privados o contenido completo de archivos.

La guía de automatización de tareas con Python muestra cómo combinar comandos, archivos, validación y registros.

Errores frecuentes

  • Construir una cadena con entrada del usuario y shell=True.
  • Ignorar el código de retorno.
  • No definir timeout para procesos externos.
  • Depender del directorio actual.
  • Suponer que stdout siempre contiene datos válidos.
  • Reemplazar todas las variables de entorno.
  • Registrar argumentos sensibles.
  • Usar comandos del sistema para tareas que pathlib resuelve mejor.

Conclusión

subprocess.run() permite integrar herramientas externas con un control claro sobre argumentos, salida, errores y tiempo máximo. Utiliza listas de argumentos, activa check=True, captura únicamente lo necesario y evita una shell cuando el comando pueda ejecutarse directamente. Con estas prácticas, los scripts de automatización resultan más seguros, portables y fáciles de diagnosticar.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Sistema de backup automático de arquivos usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo automatizar copias de seguridad con Python

    Aprende a automatizar copias de seguridad con Python usando pathlib, shutil, fechas, verificación, registros y una estrategia segura de restauración.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    representação de automação com ícones de engrenagens, gráficos e pessoas no background
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo automatizar tareas cotidianas con Python

    Aprende a automatizar tareas con Python: organizar archivos, renombrar lotes, procesar CSV, crear backups, usar logs y programar scripts.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    logo do BeautifulSoup em um fundo branco
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Web scraping con Python, Requests y BeautifulSoup

    Aprende web scraping con Python, Requests y BeautifulSoup: descarga páginas, selecciona elementos, limpia datos, pagina, maneja errores y exporta resultados.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Criação de bot Telegram com Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear un bot de Telegram con Python

    Crea un bot de Telegram con Python: configura BotFather, protege el token, maneja comandos y mensajes, añade botones, archivos, logging

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Automação web com Selenium usando Python
    Automatización y ScriptsDesarrollo Web
    Foto de perfil de Leandro Hirt da Academify

    Selenium con Python: automatización web completa

    Aprende Selenium con Python para controlar navegadores, localizar elementos, usar esperas, completar formularios, tomar capturas y crear pruebas fiables.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Geração de arquivos PDF usando biblioteca FPDF em Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear archivos PDF con Python y FPDF

    Aprende a crear PDF con Python y fpdf2: páginas, fuentes, párrafos, imágenes, tablas, Unicode, rutas, informes y manejo de errores.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026