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
python3cada 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
python3antes 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:
- lo conviertes a ejecutable,
- renombras el archivo final como
myip, - lo copias a
/usr/local/bin/myip, - 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/bino~/.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/binpara el comando,- y el proyecto en tu carpeta personal o en
~/.local/share/tuappsi 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.



