El Shebang es una de esas pequeñas piezas de Linux que parecen simples, pero que esconden mucho más de lo que aparentan. Está formado por dos caracteres, #!, colocados al inicio de un script, y sirve para indicar qué intérprete debe ejecutar ese archivo.
Por ejemplo:
#!/bin/bash
echo "Hola desde Bash"
O en Python:
#!/usr/bin/env python3
print("Hola desde Python")
A simple vista parece una línea decorativa, pero no lo es. El Shebang permite que un script pueda ejecutarse directamente como si fuera un programa:
./script.sh
en lugar de tener que llamar manualmente al intérprete:
bash script.sh
La diferencia parece pequeña, pero es fundamental para entender cómo Linux ejecuta scripts, cómo funciona la automatización, cómo se crean herramientas de línea de comandos y por qué ciertos errores como bad interpreter, permission denied o /usr/bin/env: python3\r aparecen con tanta frecuencia.
En este artículo vamos a ver qué es el Shebang, cómo funciona internamente en Linux, qué ocurre en el kernel cuando ejecutas un script, cuándo usar #!/bin/bash, cuándo usar #!/usr/bin/env bash, cómo aplicarlo en Bash y Python, y cuáles son los errores más comunes.
Qué es el Shebang
Tabla del contenido
El Shebang es la primera línea de un script cuando empieza con los caracteres:
#!
Después de esos dos caracteres se indica la ruta del intérprete que debe ejecutar el archivo.
Ejemplo:
#!/bin/bash
Esto significa:
“Ejecuta este archivo usando
/bin/bashcomo intérprete”.
Otro ejemplo:
#!/usr/bin/env python3
Esto significa:
“Busca
python3en elPATHdel sistema y usa ese intérprete para ejecutar este archivo”.
El Shebang también se conoce como:
- hashbang
- sharp-bang
- pound-bang
- sha-bang
- línea
#!
En la práctica, todos esos nombres hacen referencia a lo mismo: la instrucción que le dice al sistema operativo qué programa debe interpretar el contenido del script.
Sintaxis básica del Shebang
La sintaxis general es:
#!ruta-del-intérprete [argumento-opcional]
Por ejemplo:
#!/bin/bash
#!/bin/sh
#!/usr/bin/env bash
#!/usr/bin/env python3
#!/usr/bin/perl
#!/usr/bin/env php
La línea debe estar al principio del archivo. No puede ir en la segunda línea ni después de un comentario.
Correcto:
#!/bin/bash
echo "Hola"
Incorrecto:
# Este script imprime un saludo
#!/bin/bash
echo "Hola"
En el segundo caso, el sistema no reconocerá el Shebang porque no aparece como primera línea real del archivo.
Por qué el Shebang debe ir en la primera línea
Linux no escanea todo el archivo buscando #!. Cuando intentas ejecutar un archivo, el kernel mira el inicio del archivo para decidir cómo tratarlo.
Si los dos primeros bytes son:
#!
entonces lo interpreta como un script con Shebang.
Si no aparecen ahí, el kernel no usa esa línea para resolver el intérprete.
Por eso esta línea:
#!/bin/bash
debe ser literalmente la primera línea del archivo.
Incluso una línea vacía antes del Shebang puede romper el comportamiento esperado:
#!/bin/bash
echo "Esto puede fallar si se ejecuta directamente"
Primer ejemplo: script Bash con Shebang
Crea un archivo llamado hola.sh:
nano hola.sh
Añade este contenido:
#!/bin/bash
echo "Hola desde Bash"
echo "Este script se está ejecutando con: $SHELL"
Guarda el archivo y dale permisos de ejecución:
chmod +x hola.sh
Ahora ejecútalo directamente:
./hola.sh
Salida esperada:
Hola desde Bash
Este script se está ejecutando con: /bin/bash
Aquí el Shebang permite que el sistema sepa que debe usar /bin/bash para interpretar el archivo.
Segundo ejemplo: script Python con Shebang
Crea un archivo llamado saludo.py:
nano saludo.py
Añade:
#!/usr/bin/env python3
print("Hola desde Python")
Dale permisos de ejecución:
chmod +x saludo.py
Ejecuta el archivo directamente:
./saludo.py
Salida esperada:
Hola desde Python
Sin el Shebang, el sistema no sabría por sí solo si ese archivo debe ejecutarse con Python, Bash, Perl, Ruby, PHP u otro intérprete.
Qué ocurre realmente cuando ejecutas un script en Linux
Cuando escribes:
./hola.sh
no estás ejecutando “texto”. Estás pidiendo al sistema operativo que ejecute un archivo.
De forma simplificada, ocurre esto:
Usuario ejecuta ./hola.sh
↓
La shell recibe el comando
↓
La shell llama a execve()
↓
El kernel abre el archivo
↓
El kernel lee el inicio del archivo
↓
Detecta los caracteres #!
↓
Extrae la ruta del intérprete
↓
Ejecuta el intérprete
↓
Le pasa el script como argumento
↓
El intérprete lee y ejecuta el contenido del script
Es decir, el script no se ejecuta “solo”. Lo ejecuta un intérprete.
Cuando el archivo empieza con:
#!/bin/bash
Linux termina ejecutando algo equivalente a:
/bin/bash ./hola.sh
Cuando empieza con:
#!/usr/bin/env python3
Linux termina ejecutando algo conceptualmente parecido a:
/usr/bin/env python3 ./saludo.py
Y luego env busca python3 en el PATH.
El papel de execve()
En Linux, una de las llamadas al sistema más importantes para entender este proceso es execve().
No necesitas usar execve() directamente en tus scripts diarios, pero entender su papel ayuda a comprender qué hace realmente el sistema.
Cuando una shell como Bash intenta ejecutar un archivo, utiliza funciones de la familia exec. A bajo nivel, Linux usa execve() para reemplazar el programa actual por otro programa.
Esto es importante: execve() no crea un nuevo proceso por sí misma. Lo que hace es reemplazar la imagen del proceso actual por un nuevo programa.
Cuando ejecutas:
./script.sh
la shell crea un proceso hijo y ese proceso hijo llama a execve() para intentar ejecutar ./script.sh.
El kernel revisa el archivo. Si es un binario ejecutable, lo carga como programa. Si es un script que empieza con #!, busca el intérprete indicado en esa línea y ejecuta ese intérprete pasándole el script como argumento.
Cómo interpreta Linux la línea #!
La lógica interna es más o menos esta:
1. El kernel intenta ejecutar el archivo.
2. Comprueba si los dos primeros caracteres son #!.
3. Si no lo son, ese manejador no aplica.
4. Si sí lo son, analiza la primera línea.
5. Extrae la ruta del intérprete.
6. Extrae un argumento opcional, si existe.
7. Reorganiza los argumentos.
8. Abre el intérprete.
9. Reinicia la ejecución usando ese intérprete.
Por ejemplo, este Shebang:
#!/bin/bash
indica que el intérprete es:
/bin/bash
Este otro:
#!/usr/bin/env bash
indica que el intérprete inicial es:
/usr/bin/env
y que bash será el argumento pasado a env.
Por eso #!/usr/bin/env bash no significa exactamente “ejecuta Bash directamente”. Significa:
“Ejecuta
/usr/bin/envy pídele que encuentrebashusando elPATH”.
Diferencia entre ejecutar con Shebang y llamar al intérprete manualmente
Este punto es clave.
Supongamos que tienes este script:
#!/bin/bash
echo "Hola"
Puedes ejecutarlo de dos formas:
./script.sh
o:
bash script.sh
Cuando usas:
./script.sh
el Shebang importa. El sistema mira la primera línea y usa el intérprete indicado.
Pero cuando usas:
bash script.sh
el Shebang prácticamente no decide nada, porque ya has elegido tú el intérprete: bash.
Esto explica por qué un script puede funcionar así:
bash script.sh
pero fallar así:
./script.sh
En el primer caso, llamas explícitamente a Bash. En el segundo, dependes de tres cosas:
- Que el archivo tenga permisos de ejecución.
- Que el Shebang esté bien escrito.
- Que el intérprete indicado exista y pueda ejecutarse.
Permisos de ejecución: por qué necesitas chmod +x
El Shebang no sustituye los permisos de ejecución.
Puedes tener un script perfecto:
#!/bin/bash
echo "Hola"
pero si no tiene permisos de ejecución, al intentar ejecutarlo así:
./script.sh
puedes obtener:
Permission denied
Para solucionarlo:
chmod +x script.sh
Luego:
./script.sh
La idea es simple:
- El Shebang indica con qué intérprete ejecutar el archivo.
- Los permisos indican si el archivo puede ejecutarse.
Son dos cosas distintas.
Puedes comprobar los permisos con:
ls -l script.sh
Ejemplo:
-rwxr-xr-x 1 david david 42 jun 18 10:30 script.sh
La x indica permiso de ejecución.
#!/bin/bash vs #!/usr/bin/env bash
Una de las dudas más comunes es qué Shebang conviene usar en scripts Bash:
#!/bin/bash
o:
#!/usr/bin/env bash
Ambas opciones son válidas, pero no significan exactamente lo mismo.
Usar #!/bin/bash
Cuando usas:
#!/bin/bash
estás indicando una ruta absoluta. El sistema intentará ejecutar Bash exactamente desde:
/bin/bash
Ventajas:
- Es explícito.
- Es predecible.
- No depende del
PATH. - Es buena opción para scripts de sistema o entornos controlados.
Desventajas:
- Bash puede estar en otra ruta en algunos sistemas.
- Es menos flexible en entornos donde se usan versiones personalizadas de Bash.
Puedes comprobar dónde está Bash con:
which bash
o mejor:
command -v bash
Ejemplo:
/usr/bin/bash
En muchas distribuciones modernas /bin puede ser un enlace simbólico hacia /usr/bin, pero no conviene asumirlo siempre si buscas máxima portabilidad.
Usar #!/usr/bin/env bash
Cuando usas:
#!/usr/bin/env bash
estás usando env para buscar bash en el PATH.
Ventajas:
- Es más portable entre sistemas.
- Respeta el entorno del usuario.
- Funciona bien cuando el intérprete está instalado en una ruta no estándar.
- Es útil en entornos con gestores de versiones.
Desventajas:
- Depende del
PATH. - Puede ejecutar un intérprete inesperado si el
PATHestá manipulado. - En scripts sensibles o administrativos puede ser menos predecible.
En la práctica:
- Para scripts personales, herramientas de desarrollo o proyectos portables:
#!/usr/bin/env bash. - Para scripts de sistema, automatizaciones críticas o entornos cerrados:
#!/bin/basho la ruta absoluta comprobada.
#!/bin/sh vs #!/bin/bash
Otro error común es pensar que sh y bash son siempre lo mismo.
No lo son.
Este Shebang:
#!/bin/sh
indica que el script debe ejecutarse con la shell del sistema compatible con POSIX.
Este otro:
#!/bin/bash
indica que debe ejecutarse con Bash.
La diferencia importa porque Bash tiene características que no existen necesariamente en sh.
Por ejemplo, este script usa arrays de Bash:
#!/bin/bash
nombres=("Ana" "Luis" "David")
echo "${nombres[2]}"
Eso funciona en Bash, pero puede fallar si lo ejecutas con sh.
En cambio, un script POSIX más portable sería:
#!/bin/sh
nombre="David"
echo "$nombre"
Regla práctica:
- Usa
#!/bin/shsi quieres portabilidad POSIX. - Usa
#!/bin/bashsi vas a usar características específicas de Bash. - No uses
#!/bin/shen un script que realmente depende de Bash.
Shebang en Python: python, python3, env y entornos virtuales
En Python, el Shebang también es importante.
Opciones comunes:
#!/usr/bin/python3
#!/usr/bin/env python3
La primera usa una ruta absoluta. La segunda busca python3 en el PATH.
Para scripts de desarrollo, normalmente es preferible:
#!/usr/bin/env python3
porque funciona mejor con entornos virtuales.
Ejemplo:
#!/usr/bin/env python3
import sys
print("Ejecutable de Python:", sys.executable)
print("Versión:", sys.version)
Si activas un entorno virtual:
source .venv/bin/activate
y luego ejecutas:
./script.py
el uso de /usr/bin/env python3 permite que el sistema encuentre el python3 del entorno virtual, siempre que el PATH esté configurado correctamente.
Eso es muy útil en proyectos reales, porque evita atar el script a una ruta fija del sistema.
Tabla comparativa de Shebangs comunes
| Shebang | Uso típico | Ventaja | Riesgo o limitación |
|---|---|---|---|
#!/bin/bash | Scripts Bash en Linux | Predecible y directo | Bash debe existir en esa ruta |
#!/usr/bin/env bash | Scripts portables | Busca Bash en el PATH | Depende del entorno |
#!/bin/sh | Scripts POSIX | Muy portable | No soporta todas las funciones de Bash |
#!/usr/bin/python3 | Scripts Python en sistema fijo | Ruta explícita | Menos flexible con entornos virtuales |
#!/usr/bin/env python3 | Scripts Python portables | Compatible con venv y PATH | Puede usar otro Python si el PATH cambia |
#!/usr/bin/env node | Scripts Node.js | Útil con nvm/asdf | Depende del PATH |
#!/usr/bin/env php | Scripts PHP CLI | Portable | Depende del PATH |
Errores comunes con Shebang
El Shebang parece simple, pero muchos errores de scripts vienen de esta línea.
Veamos los más frecuentes.
Error: Permission denied
Ejemplo:
./script.sh
Salida:
bash: ./script.sh: Permission denied
Causa probable:
El archivo no tiene permisos de ejecución.
Solución:
chmod +x script.sh
./script.sh
Error: bad interpreter: No such file or directory
Ejemplo:
bad interpreter: No such file or directory
Causas posibles:
- La ruta del intérprete no existe.
- El Shebang está mal escrito.
- El archivo tiene saltos de línea de Windows.
- El intérprete no está instalado.
Ejemplo incorrecto:
#!/bin/bahs
Aquí hay un typo: bahs en lugar de bash.
Comprueba la ruta correcta:
command -v bash
Salida posible:
/usr/bin/bash
Entonces puedes usar:
#!/usr/bin/bash
o:
#!/usr/bin/env bash
Error por saltos de línea de Windows: /usr/bin/env: ‘python3\r’
Este es uno de los errores más comunes cuando editas scripts en Windows y luego los ejecutas en Linux, WSL, Docker o un servidor.
Error típico:
/usr/bin/env: ‘python3\r’: No such file or directory
El problema es el carácter \r, que viene de los saltos de línea CRLF de Windows.
Linux espera saltos de línea LF. Si el archivo tiene CRLF, el sistema puede interpretar el Shebang como:
#!/usr/bin/env python3\r
Entonces intenta buscar un programa llamado python3\r, no python3.
Soluciones:
dos2unix script.py
O con sed:
sed -i 's/\r$//' script.py
También puedes configurar tu editor para guardar archivos con formato LF.
En VS Code, por ejemplo, puedes cambiar CRLF a LF desde la barra inferior.
Error: Exec format error
Puedes ver algo como:
cannot execute: Exec format error
Esto puede pasar si el archivo no tiene un formato ejecutable reconocido y tampoco tiene un Shebang válido.
Ejemplo problemático:
echo "Hola"
Si guardas eso como script y haces:
chmod +x script
./script
puede fallar porque no hay una primera línea que indique qué intérprete debe usarse.
Solución:
#!/bin/bash
echo "Hola"
Error: Shebang en la segunda línea
Incorrecto:
# Script de prueba
#!/bin/bash
echo "Hola"
Correcto:
#!/bin/bash
# Script de prueba
echo "Hola"
El Shebang debe ser la primera línea real del archivo.
Error: usar Bash pero declarar sh
Ejemplo:
#!/bin/sh
nombres=("Ana" "Luis" "David")
echo "${nombres[0]}"
Este script probablemente fallará porque los arrays no forman parte de sh POSIX.
Solución:
#!/bin/bash
nombres=("Ana" "Luis" "David")
echo "${nombres[0]}"
La regla es sencilla: el Shebang debe declarar el intérprete que tu script realmente necesita.
Limitaciones del Shebang
Aunque el Shebang es muy útil, tiene limitaciones.
1. Debe estar en la primera línea
No puede ir precedido por comentarios, espacios raros o líneas vacías.
2. El intérprete debe existir
Si escribes:
#!/opt/custom/bash
pero esa ruta no existe, el script fallará.
3. Hay límites de longitud
La línea del Shebang no puede ser arbitrariamente larga. En Linux moderno, el texto procesado después de #! tiene un límite. Por eso conviene mantener esta línea simple y clara.
4. Los argumentos múltiples no siempre son portables
Este Shebang puede parecer razonable:
#!/usr/bin/env python3 -O
pero en muchos sistemas no se interpreta como dos argumentos separados. Puede tratarse como un único argumento completo, provocando errores.
Para varios argumentos con env, en sistemas que soportan GNU env, puedes usar -S:
#!/usr/bin/env -S python3 -O
Aun así, si buscas portabilidad máxima, evita Shebangs demasiado complejos.
Qué hace /usr/bin/env en un Shebang
env es un programa que puede ejecutar otro comando en un entorno determinado.
Cuando escribes:
#!/usr/bin/env bash
el sistema ejecuta:
/usr/bin/env bash ./script.sh
Luego env busca bash usando la variable PATH.
Puedes ver tu PATH con:
echo "$PATH"
Ejemplo:
/usr/local/bin:/usr/bin:/bin
Si bash está en alguna de esas rutas, env lo encontrará.
Esto permite que el mismo script funcione en sistemas donde Bash puede estar en rutas diferentes.
Cuándo usar /usr/bin/env
Usa /usr/bin/env cuando quieras que el sistema encuentre el intérprete según el entorno actual.
Ejemplos recomendados:
#!/usr/bin/env bash
#!/usr/bin/env python3
#!/usr/bin/env node
Casos típicos:
- scripts de desarrollo
- herramientas CLI
- proyectos compartidos entre sistemas
- entornos virtuales de Python
- gestores de versiones como pyenv, nvm o asdf
- scripts que pueden ejecutarse en Linux, macOS o WSL
Cuándo evitar /usr/bin/env
Evita /usr/bin/env cuando necesites control absoluto sobre el intérprete.
Por ejemplo:
- scripts de administración del sistema
- scripts ejecutados por
root - automatizaciones críticas
- entornos de producción muy controlados
- scripts donde el
PATHpuede ser manipulado
En esos casos, una ruta absoluta puede ser más segura:
#!/bin/bash
o:
#!/usr/bin/python3
La razón es que /usr/bin/env depende del PATH. Si el PATH apunta primero a un directorio inseguro, podría ejecutarse un binario inesperado.
Ejemplo de riesgo conceptual:
PATH="/tmp:$PATH"
Si alguien coloca un ejecutable llamado python3 en /tmp, un script con:
#!/usr/bin/env python3
podría terminar ejecutando ese binario antes que el Python real del sistema.
En scripts personales no suele ser un problema grave, pero en scripts privilegiados o sensibles sí importa.
Shebang, PATH y seguridad
La variable PATH define dónde busca el sistema los comandos cuando no se proporciona una ruta absoluta.
Por ejemplo, cuando escribes:
ls
la shell busca ls dentro de las rutas listadas en PATH.
Cuando usas:
#!/usr/bin/env bash
también estás delegando esa búsqueda al entorno.
Esto es cómodo, pero debes entender la implicación:
- Ruta absoluta: más control.
/usr/bin/env: más flexibilidad.- Flexibilidad sin control puede abrir la puerta a errores o riesgos.
Buenas prácticas:
#!/bin/bash
set -euo pipefail
Y en scripts sensibles, definir un PATH seguro:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export PATH
Shebang y WSL
En WSL, el Shebang funciona como en Linux porque estás ejecutando un entorno Linux sobre Windows.
El problema más común no es WSL en sí, sino los archivos editados desde Windows con saltos de línea CRLF.
Ejemplo de error:
/usr/bin/env: ‘bash\r’: No such file or directory
Solución:
dos2unix script.sh
O configurar Git para manejar saltos de línea correctamente.
Para proyectos que se ejecutan en Linux/WSL, suele ser recomendable usar LF.
Puedes configurar Git así:
git config --global core.autocrlf input
Esto ayuda a evitar que los scripts terminen con saltos de línea incompatibles.
Shebang y Docker
En Docker, el Shebang también importa.
Ejemplo de script de entrada:
#!/bin/sh
set -e
echo "Iniciando contenedor..."
exec "$@"
Si lo usas como ENTRYPOINT, necesitas que tenga permisos de ejecución:
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Errores comunes en Docker:
permission denied
Solución:
RUN chmod +x /entrypoint.sh
Otro error:
exec /entrypoint.sh: no such file or directory
Aunque el archivo exista, puede deberse a CRLF. Convierte el archivo a LF.
También debes tener cuidado con la imagen base. En Alpine Linux, por ejemplo, normalmente tienes /bin/sh, pero no necesariamente /bin/bash.
Este Shebang puede fallar:
#!/bin/bash
si Bash no está instalado.
En Alpine, para scripts simples, suele ser mejor:
#!/bin/sh
O instalar Bash explícitamente si lo necesitas.
Buenas prácticas al escribir Shebangs
1. Usa el intérprete correcto
No declares sh si estás usando Bash.
Mal:
#!/bin/sh
array=("uno" "dos")
Bien:
#!/bin/bash
array=("uno" "dos")
2. Usa /usr/bin/env para scripts portables
Para herramientas de desarrollo:
#!/usr/bin/env bash
Para Python:
#!/usr/bin/env python3
3. Usa rutas absolutas en scripts críticos
Para scripts de sistema:
#!/bin/bash
o la ruta real comprobada:
#!/usr/bin/bash
4. Añade permisos de ejecución
chmod +x script.sh
5. Evita CRLF
Convierte archivos editados en Windows:
dos2unix script.sh
O:
sed -i 's/\r$//' script.sh
6. Comprueba el intérprete
command -v bash
command -v python3
command -v node
7. Mantén el Shebang simple
Evita líneas demasiado largas o con muchos argumentos.
Mejor:
#!/usr/bin/env python3
que:
#!/usr/bin/env python3 -O -B -X dev
Si necesitas opciones complejas, plantéate moverlas al propio script o a la forma de invocarlo.
Laboratorio práctico: probando el Shebang paso a paso
Vamos a crear tres scripts para entender cuándo importa el Shebang.
Script 1: Bash correcto
cat > demo-bash.sh <<'EOF'
#!/bin/bash
echo "Ejecutado con Bash"
echo "Versión de Bash: $BASH_VERSION"
EOF
Permisos:
chmod +x demo-bash.sh
Ejecución:
./demo-bash.sh
Script 2: Bash ejecutado con sh
Ahora ejecuta el mismo script con sh:
sh demo-bash.sh
Puede que algunas partes funcionen, pero si el script usa características exclusivas de Bash, fallará.
Ejemplo:
cat > arrays.sh <<'EOF'
#!/bin/bash
nombres=("Ana" "Luis" "David")
echo "${nombres[2]}"
EOF
chmod +x arrays.sh
./arrays.sh
sh arrays.sh
La ejecución directa usará Bash por el Shebang. La ejecución con sh arrays.sh ignora la intención del Shebang y fuerza el uso de sh.
Script 3: Python portable
cat > demo-python.py <<'EOF'
#!/usr/bin/env python3
import sys
print("Hola desde Python")
print(sys.executable)
EOF
chmod +x demo-python.py
./demo-python.py
Este ejemplo te muestra qué ejecutable de Python está usando realmente el script.
Cómo depurar problemas con Shebang
Cuando un script falla, sigue este checklist.
1. Ver la primera línea
head -n 1 script.sh
2. Ver caracteres ocultos
cat -A script.sh | head
Si ves algo como:
#!/usr/bin/env bash^M$
tienes saltos de línea CRLF.
3. Comprobar permisos
ls -l script.sh
4. Comprobar intérprete
command -v bash
command -v python3
5. Ejecutar explícitamente
bash script.sh
python3 script.py
Si funciona explícitamente pero no con ./script, el problema probablemente está en:
- permisos
- Shebang
- saltos de línea
- ruta del intérprete
Historia breve del Shebang
El Shebang forma parte de la tradición Unix. Su función nació de una necesidad práctica: permitir que los scripts de texto pudieran ejecutarse de forma similar a los binarios.
Sin esta convención, el usuario tendría que escribir siempre:
sh script.sh
python3 script.py
perl script.pl
Con el Shebang, el sistema puede delegar la ejecución al intérprete correcto automáticamente.
Esto convirtió a los scripts en ciudadanos de primera clase dentro del ecosistema Unix: pequeños programas ejecutables, automatizables y combinables con otras herramientas.
Por eso el Shebang sigue siendo tan importante hoy en Linux, macOS, BSD, WSL, Docker y servidores de producción.
Preguntas frecuentes sobre Shebang
¿El Shebang es obligatorio?
No siempre.
Si ejecutas un script así:
bash script.sh
no necesitas Shebang porque ya estás indicando el intérprete.
Pero si quieres ejecutarlo directamente:
./script.sh
entonces sí necesitas un Shebang válido y permisos de ejecución.
¿Qué significa #!/bin/bash?
Significa que el archivo debe ejecutarse usando Bash desde la ruta:
/bin/bash
Es una ruta absoluta al intérprete.
¿Qué significa #!/usr/bin/env bash?
Significa que el sistema debe ejecutar /usr/bin/env, y que env debe buscar bash en el PATH.
Es más portable, pero depende del entorno.
¿Qué es mejor: /bin/bash o /usr/bin/env bash?
Depende del caso.
Para scripts de sistema o entornos controlados:
#!/bin/bash
Para scripts portables o de desarrollo:
#!/usr/bin/env bash
¿Qué pasa si no pongo Shebang?
Si ejecutas el archivo directamente, puede fallar porque el sistema no sabe qué intérprete usar.
Si lo ejecutas pasando el archivo a un intérprete, sí puede funcionar:
bash script.sh
python3 script.py
¿Puedo usar Shebang en Windows?
Windows no usa Shebang de forma nativa como Linux o Unix. Sin embargo, herramientas como Git Bash, WSL, Cygwin o MSYS2 sí pueden reconocerlo dentro de sus entornos.
En WSL funciona como en Linux.
¿Por qué aparece /usr/bin/env: python3\r?
Porque el archivo probablemente tiene saltos de línea de Windows, conocidos como CRLF.
Convierte el archivo a formato Unix:
dos2unix script.py
¿El Shebang afecta si ejecuto python3 script.py?
No de forma relevante.
Cuando ejecutas:
python3 script.py
ya estás eligiendo el intérprete manualmente. El Shebang importa principalmente cuando ejecutas el archivo directamente:
./script.py
¿Puedo pasar argumentos en el Shebang?
Sí, pero con limitaciones.
Ejemplo simple:
#!/bin/bash -e
Sin embargo, los argumentos múltiples pueden no comportarse igual en todos los sistemas.
Para varios argumentos con GNU env, puede usarse:
#!/usr/bin/env -S python3 -O
Pero no conviene abusar de esto si buscas portabilidad.
¿Qué Shebang debo usar para Python?
Para scripts portables:
#!/usr/bin/env python3
Para scripts de sistema donde quieres usar una ruta concreta:
#!/usr/bin/python3
Conclusión
El Shebang es mucho más que una primera línea curiosa en un script. Es el mecanismo que permite que Linux sepa qué intérprete debe usar para ejecutar un archivo de texto como si fuera un programa.
Cuando escribes:
#!/bin/bash
estás atando el script a Bash en una ruta concreta.
Cuando escribes:
#!/usr/bin/env bash
estás delegando la búsqueda de Bash al PATH.
Cuando escribes:
#!/usr/bin/env python3
estás haciendo que un script Python pueda ejecutarse directamente y adaptarse mejor a entornos virtuales o configuraciones portables.
Dominar el Shebang implica entender varios conceptos importantes de Linux:
- permisos de ejecución
- rutas absolutas
- variable
PATH - intérpretes
- llamadas
exec - diferencias entre
shybash - saltos de línea LF y CRLF
- seguridad en scripts
- automatización real
Por eso, aunque solo sean dos caracteres, #! es una puerta de entrada a cómo Linux ejecuta scripts por dentro.
Si estás aprendiendo Bash, Python, automatización o administración de sistemas, entender bien el Shebang no es un detalle menor: es una base que te evitará errores y te ayudará a escribir scripts más portables, seguros y profesionales.
