Cómo ejecutar tus scripts de Python en Linux y convertirlos en comandos de consola

Cómo ejecutar tus scripts de Python en Linux y convertirlos en comandos de consola

Cuando empiezas a crear scripts en Python para Linux, una de las primeras dudas que aparece es esta: ¿cuál es la mejor forma de ejecutarlos?

Porque una cosa es correr un archivo con:

python3 script.py

y otra muy distinta es poder escribir algo como:

myip

o:

tool

como si fuera un comando nativo del sistema.

La buena noticia es que en Linux existen varias formas de lograrlo. Algunas son muy simples y perfectas para uso personal, otras son mejores para proyectos grandes, y otras son más “profesionales” cuando quieres distribuir una herramienta o dejarla bien organizada dentro del sistema.

Además, entender esto también te ayuda a comprender mejor la estructura de directorios de Linux, porque no todo se debe guardar en cualquier carpeta. Hay rutas pensadas para binarios, otras para datos compartidos, otras para configuración, y usar la correcta hace que tu herramienta quede más ordenada y más fácil de mantener.

1. La forma más básica: ejecutar el script directamente con Python

La manera más sencilla de correr un script es esta:

python3 mi_script.py

Esto funciona muy bien cuando estás desarrollando, probando cosas o usando un script ocasionalmente.

Ventajas

  • Es la forma más simple.
  • No necesitas instalar nada extra.
  • Es ideal para pruebas rápidas.

Desventajas

  • Tienes que escribir python3 cada vez.
  • Si el proyecto tiene muchas dependencias, puede volverse incómodo.
  • No se siente como una herramienta integrada al sistema.

2. Hacer el script ejecutable con shebang

Otra forma muy común es poner al inicio del archivo:

#!/usr/bin/env python3

Luego le das permisos de ejecución:

chmod +x mi_script.py

Y entonces ya puedes ejecutarlo así:

./mi_script.py

¿Qué hace el shebang?

Le dice a Linux con qué intérprete debe abrir ese archivo. En este caso, con python3.

Ventajas

  • Muy práctico.
  • No necesitas escribir python3 antes del archivo.
  • Es ideal para scripts pequeños.

Desventajas

  • Sigues teniendo que escribir ./ si estás en la carpeta actual.
  • Si quieres usarlo como comando global, todavía necesitas colocarlo en una ruta incluida en el PATH.

3. Convertir un script pequeño en un comando usando /usr/local/bin

Esta es una de las formas más limpias y recomendables cuando hiciste una herramienta local para tu máquina.

Supongamos que tienes un script llamado myip.py. Puedes convertirlo en binario con PyInstaller o dejarlo como script ejecutable, pero lo importante es que el nombre final del archivo será el nombre del comando.

Por ejemplo, si el archivo final se llama:

myip

y lo copias aquí:

/usr/local/bin/myip

entonces podrás ejecutarlo desde cualquier terminal simplemente escribiendo:

myip

La razón es que /usr/local/bin está pensado para programas instalados localmente por el administrador del sistema, y debe mantenerse separado de lo que instala la distribución. El FHS indica justamente que /usr/local es para software instalado localmente y que debe estar protegido de ser sobrescrito por actualizaciones del sistema.

Ejemplo

sudo cp myip /usr/local/bin/myip
sudo chmod +x /usr/local/bin/myip

Ventajas

  • Muy limpio.
  • Muy cómodo para herramientas personales.
  • No mezclas tus archivos con los paquetes del sistema.
  • Es una ruta estándar para binarios locales.

Desventajas

  • Si tu herramienta depende de muchos archivos, no conviene meter todo ahí.
  • Esa carpeta es mejor para el “lanzador” o binario principal, no para un proyecto grande completo.

Cuándo usarlo

Úsalo cuando:

  • tu script es pequeño,
  • quieres invocarlo como comando,
  • y no quieres complicarte demasiado.

4. Crear un lanzador en /usr/local/bin y guardar los archivos en /opt

Esta es una muy buena práctica cuando ya no tienes un solo archivo, sino un proyecto más grande con varias carpetas, módulos y funciones distribuidas.

Sería algo así:

Lanzador en /usr/local/bin/tool

dentro del archivo tool escribe ordenes que quieres que ejecute:

#!/bin/bash
cd /opt/tools-opers
myenv/bin/python3 tools.py

Y luego guardar el proyecto completo en:

/opt/tools-opers

Entonces al escribir:

tool

se ejecuta ese lanzador.

Ejemplo de estructura

/opt/tools-opers/
├── bin/
│ └── tool
├── myenv/
├── tools.py
├── core/
├── modules/
└── assets/

¿Por qué funciona bien esta estructura?

Porque estás separando:

  • el comando → en /usr/local/bin
  • los archivos del proyecto → en /opt/tools-opers

o también podrias guardar el ejecutable tool en la misma ruta de tu herramienta y puedes crear un acceso directorio y enlazarlo

sudo ln -s /opt/tools-opers/bin/tool /usr/local/bin/tool

Ejemplo de lanzador

#!/bin/bash
cd /opt/tools-opers
./myenv/bin/python3 tools.py

Ventajas

  • Muy buena para proyectos grandes.
  • Mantiene todo contenido en una sola carpeta clara.
  • Es excelente si tu herramienta tiene dependencias, recursos, módulos, plantillas o varios scripts.

Desventajas

  • Es más estructurado, así que requiere más organización.
  • Para scripts pequeños puede ser excesivo.

Cuándo usarlo

Úsalo cuando:

  • tu proyecto tiene muchas carpetas,
  • incluye entorno virtual,
  • usa archivos auxiliares,
  • o quieres tener una instalación más formal.

5. Usar ~/.local/bin para comandos solo del usuario

No todo tiene que instalarse a nivel sistema. Si el comando es solo para ti y no quieres usar sudo, una ruta excelente es:

~/.local/bin

La especificación XDG indica que los ejecutables específicos del usuario pueden almacenarse en ~/.local/bin, y que las distribuciones deberían procurar incluirlo en el PATH. systemd también lo describe como lugar para ejecutables que deben aparecer en el PATH, aunque advierte que conviene reservarlo para comandos invocados directamente desde la shell y usar nombres únicos para evitar choques.

Ejemplo

mkdir -p ~/.local/bin
cp myip ~/.local/bin/myip
chmod +x ~/.local/bin/myip

Ventajas

  • No necesitas permisos de administrador.
  • Perfecto para herramientas personales.
  • Muy cómodo en tu propio entorno de trabajo.

Desventajas

  • Solo queda disponible para ese usuario.
  • Si otro usuario entra al sistema, no tendrá ese comando.

Cuándo usarlo

Es una de las opciones más recomendables para:

  • scripts personales,
  • herramientas de uso diario,
  • atajos de consola hechos por ti.

De hecho, para muchos casos ~/.local/bin es la mejor opción para uso personal, mientras que /usr/local/bin es mejor si quieres que esté disponible a nivel del sistema.


6. Crear un wrapper .sh o lanzador Bash

Crear un pequeño script Bash que sea el “puente” entre el comando y tu proyecto Python.

Por ejemplo:

#!/bin/bash
cd /opt/tools-opers
./myenv/bin/python3 tools.py

Esto se llama normalmente wrapper o launcher script.

¿Por qué es útil?

Porque desacoplas el comando real de la estructura interna del proyecto. El usuario ejecuta tool, pero tú por detrás puedes controlar:

  • en qué carpeta entra,
  • qué entorno virtual usa,
  • qué archivo principal corre,
  • qué variables de entorno cargas antes,
  • o incluso qué argumentos pasas.

También podrías mejorarlo

En vez de depender de cd, puedes usar rutas absolutas para que sea más robusto:

#!/bin/bash
/opt/tools-opers/myenv/bin/python3 /opt/tools-opers/tools.py "$@"

Ese "$@" hace que también reciba parámetros:

tool archivo.txt --debug

Ventajas

  • Muy flexible.
  • Fácil de mantener.
  • Perfecto para proyectos grandes.

Desventajas

  • Si borras o mueves el entorno virtual, deja de funcionar.
  • No es un binario real: depende de Bash y Python.

7. Empaquetarlo como binario con PyInstaller

Esto es muy útil cuando tienes un script de un solo archivo o una herramienta simple y quieres que parezca un ejecutable real.

PyInstaller analiza tu programa y genera un ejecutable que puedes mover y llamar directamente. Luego ese archivo puede ir, por ejemplo, a /usr/local/bin. Eso reduce la dependencia visible del intérprete al momento de ejecutar, aunque el binario resultante suele ser más pesado. Esta explicación es práctica; PyInstaller no forma parte de las fuentes que cité aquí, así que tómalo como recomendación técnica basada en uso común.

Cuándo conviene

  • Cuando es una herramienta pequeña.
  • Cuando quieres distribuirla fácil.
  • Cuando no quieres depender de un launcher Bash.

Cuándo no conviene tanto

  • Si el proyecto es grande y cambia seguido.
  • Si quieres depurar fácilmente.
  • Si prefieres que todo siga siendo Python puro y modificable.

Idea práctica

Para un script como myip.py, sí tiene mucho sentido:

  1. lo conviertes a ejecutable,
  2. renombras el archivo final como myip,
  3. lo copias a /usr/local/bin/myip,
  4. y ya lo usas como comando.

8. Usar zipapp: un solo archivo ejecutable en formato Python

Python incluye oficialmente zipapp, que permite crear aplicaciones ejecutables empaquetadas en un archivo .pyz. La documentación oficial explica que estos archivos contienen código Python empaquetado y pueden ejecutarse directamente con el intérprete adecuado.

Ejemplo de uso

python3 -m zipapp miapp -o miapp.pyz -m "main:main"

Y luego:

python3 miapp.pyz

También puedes hacerlos ejecutables con shebang.

Ventajas

  • Todo queda agrupado en un solo archivo.
  • Es oficial de Python.
  • Muy práctico para ciertos tipos de herramientas.

Desventajas

  • No siempre es la opción más cómoda si dependes de librerías externas complicadas.
  • No sustituye a un binario nativo real.

Cuándo usarlo

  • Cuando quieres un solo archivo portable.
  • Cuando tu proyecto está razonablemente bien organizado.
  • Cuando no necesitas llegar al nivel de PyInstaller.

¿Y qué carpetas conviene usar para cada cosa?

Aquí es donde muchos se confunden. No se trata solo de “que funcione”, sino de guardar cada parte en la ruta adecuada.

/usr/local/bin

Para comandos y ejecutables instalados manualmente por ti o por el administrador local. Es de las rutas más recomendadas para exponer un comando global personalizado.

~/.local/bin

Para comandos personales del usuario actual. Muy recomendable si no quieres tocar el sistema completo.

/usr/share

Para datos compartidos y de solo lectura, independientes de arquitectura. Sirve bien para recursos, plantillas, textos, iconos o archivos de apoyo, pero no suele ser el mejor lugar para meter un proyecto Python completo con venv.

/opt

Para aplicaciones adicionales grandes o autocontenidas. Muy buena opción para proyectos Python grandes con varias carpetas, dependencias y estructura propia. Si además requieren configuración, el FHS reserva /etc/opt/<subdir> para la configuración específica del host y /var/opt/<subdir> para datos variables del paquete.

/etc

Para archivos de configuración del sistema o de la aplicación si quieres separar claramente código y configuración. El estándar lo define como configuración específica del host.

/var

Para datos variables: logs, cachés, estados cambiantes, archivos generados durante la ejecución. El FHS define /var justamente para datos variables, administrativos, de logging y temporales persistentes.


Rutas que normalmente NO conviene usar para esto

/usr/bin

Normalmente no es lo ideal para scripts tuyos hechos a mano, porque ahí viven muchos binarios gestionados por la distribución o el sistema de paquetes. Si algo es local, /usr/local/bin es la ruta más correcta. Esto se desprende del rol separado de /usr y /usr/local en el FHS.

/bin

Todavía menos para tus utilidades personales. Esa zona históricamente se reserva para binarios esenciales del sistema o del arranque.

/sbin o /usr/sbin

Son para utilidades administrativas del sistema, muchas veces orientadas a root. El FHS reserva /sbin, /usr/sbin y /usr/local/sbin para herramientas de administración y reparación; si tu herramienta es para administración local y la usarás como root, entonces /usr/local/sbin sí puede tener sentido.


¿Cuál método recomiendo según el caso?

Caso 1: script pequeño, un solo archivo

La opción más práctica:

  • hacerlo ejecutable,
  • o convertirlo con PyInstaller,
  • y colocarlo en /usr/local/bin o ~/.local/bin.

Ejemplo perfecto: myip.

Caso 2: proyecto Python con varias carpetas

La opción más limpia:

  • guardar el proyecto completo en /opt/mi-herramienta,
  • crear un wrapper en /usr/local/bin/tool,
  • y usar el entorno virtual desde ahí.

Caso 3: herramienta solo para ti

La opción más recomendable:

  • ~/.local/bin para el comando,
  • y el proyecto en tu carpeta personal o en ~/.local/share/tuapp si quieres organizarlo mejor.

Caso 4: quieres algo más distribuible

La opción más profesional:

  • empaquetarlo como aplicación DEB,
  • e instalarlo con dpkg.

En resumen:

La mejor opción para scripts personales pequeños

~/.local/bin

La mejor opción para comandos globales hechos por ti

/usr/local/bin

La mejor opción para proyectos grandes con varias carpetas

/opt + wrapper en /usr/local/bin

La opción rápida para un solo archivo

PyInstaller

La opción interesante y poco conocida

zipapp


Ejemplo final de estructura recomendada para una herramienta grande

/opt/tools-opers/
├── app/
│ ├── __init__.py
│ ├── main.py
│ ├── utils.py
│ └── modules/
├── myenv/
├── config/
├── assets/
└── launcher.sh

Contenido de launcher.sh:

#!/bin/bash
/opt/tools-opers/myenv/bin/python3 /opt/tools-opers/app/main.py "$@"

Luego:

sudo ln -s /opt/tools-opers/launcher.sh /usr/local/bin/tool
sudo chmod +x /opt/tools-opers/launcher.sh

Y ya lo usarías así:

tool

o con argumentos:

tool --help
tool archivo.txt

En Linux sí puedes correr tus scripts de muchas maneras, pero no todas son igual de recomendables para todos los casos.

Lo importante no es solo “hacer que corra”, sino hacer que quede bien organizado, fácil de mantener y en la ruta correcta.

Deja un comentario