El secreto de la primera línea de un script en Linux: ¿qué es realmente #!/usr/bin/env bash y #!/bin/bash?

Cuando escribes un script en Linux, por costumbre lo colocas al principio.

#!/usr/bin/env bash

o

#!/bin/bash

A simple vista parece solo un comentario… ¿Cuál es la verdadera identidad de esta línea? ¿Y en qué difieren realmente? En este artículo analizaremos a fondo esta línea y explicaremos cuándo usar cada una.


1. No es un comentario: ¿qué es un shebang?



La línea que comienza con #! se llama shebang.

#!/bin/bash

Desde la perspectiva del shell, comienza con #, por lo que parece un comentario. Pero desde la perspectiva del kernel de Linux, no es un comentario sino:

“Indica dónde está el intérprete que debe ejecutar este script”.

En otras palabras:

  • #!/bin/bash → “Ejecuta este archivo con /bin/bash”.
  • #!/usr/bin/env bash → “Busca el intérprete bash a través de env y ejecuta el archivo con él”.

2. ¿Cómo ejecuta el kernel un script?

El proceso de ejecución se simplifica así:

  1. El usuario ejecuta un script con permiso de ejecución
chmod +x script.sh
./script.sh
  1. El kernel lee script.sh.
  2. Verifica si los dos primeros caracteres son #!.
  3. Si es así, interpreta el resto de la línea como * “ruta del intérprete + argumentos” * y ejecuta ese programa pasando la ruta del script como argumento.

Por ejemplo, si la primera línea es:

#!/bin/bash

El kernel hace algo parecido a:

/bin/bash script.sh

Es decir, hace lo mismo que si hubiéramos ejecutado bash script.sh manualmente.

Nota: No debe haber espacios antes de #!. El primer carácter debe ser # y el segundo !.


3. Significado y características de #!/bin/bash



Esta es la forma más común que ves.

#!/bin/bash

Significado

  • “Este script es un script de bash y bash se encuentra en /bin/bash”.
  • El kernel siempre ejecutará /bin/bash para este script.

Ventajas

  • Claridad: siempre se usa /bin/bash, por lo que se sabe exactamente qué intérprete se emplea.
  • Rendimiento/simplicidad: no pasa por env, por lo que no hay búsqueda de ruta.
  • En la mayoría de las distribuciones de Linux, /bin/bash se considera la ubicación estándar.

Desventajas

  • Poca portabilidad
  • En algunos sistemas, bash puede estar en /usr/bin/bash, /usr/local/bin/bash, etc.
  • Algunos sistemas pueden no tener bash instalado y solo contar con /bin/sh.
  • En macOS, BSD, NixOS y ciertos entornos de contenedores, la ruta puede variar.

4. Significado y características de #!/usr/bin/env bash

Esta es la forma que ves con frecuencia en scripts modernos.

#!/usr/bin/env bash

El núcleo de esta línea es /usr/bin/env.

  • env es una utilidad que ayuda a configurar/verificar variables de entorno y a buscar programas en el PATH.
  • El kernel ejecuta algo como: bash /usr/bin/env bash script.sh
  • env busca el ejecutable bash en el PATH del sistema.

Ventajas

  1. Portabilidad: funciona en cualquier entorno donde bash esté en el PATH, sin importar su ubicación exacta.
  2. Uso del bash del usuario: si el usuario ha configurado su PATH para usar una versión específica de bash, se usará esa.
  3. Se aplica a otros intérpretes, por ejemplo: python #!/usr/bin/env python3

Desventajas

  1. Requiere que /usr/bin/env exista: la mayoría de los sistemas modernos lo tienen, pero en entornos muy especiales puede faltar.
  2. Dependencia del PATH: si el PATH está mal configurado o contiene una versión inesperada de bash, se ejecutará la versión incorrecta.
  3. Seguridad: en entornos muy sensibles, se prefiere usar rutas absolutas para evitar que el PATH determine el intérprete.

5. Comparación resumida

Categoría #!/bin/bash #!/usr/bin/env bash
Método de especificación del intérprete Ruta absoluta fija Búsqueda en PATH
Portabilidad Baja (puede romperse si la ruta difiere) Alta (solo necesita que bash esté en PATH)
Versión de bash Siempre /bin/bash La primera bash encontrada en PATH
Garantía de versión Relativamente fácil Depende del estado del PATH
Control de seguridad Más fuerte (ruta fija) Más flexible (dependiente de PATH)
Tendencia actual Estilo antiguo Recomendado en la mayoría de los casos

6. ¿Cuándo usar cada uno?

1) Scripts personales o de equipo (entornos de desarrollo comunes)

Recomendamos:

#!/usr/bin/env bash
  • Los servidores, entornos locales y CI pueden tener bash en distintas ubicaciones.
  • Usar env ofrece mayor flexibilidad y es la práctica moderna.

2) Scripts de producción en un entorno fijo

Si todos los servidores usan /bin/bash y el entorno es estable:

#!/bin/bash
  • Garantiza que siempre se use el mismo intérprete.
  • Reduce la posibilidad de comportamientos inesperados por cambios en el PATH.

3) Si quieres máxima portabilidad

Si existe la posibilidad de que bash no esté instalado, considera usar sh:

#!/bin/sh
  • sh es más universal, pero no soporta características específicas de bash.

7. Consejos prácticos al usar #!/usr/bin/env bash

1) Cómo ejecutar el script

Para aprovechar el shebang, no basta con:

bash script.sh   # El shebang se ignora

En su lugar, haz:

chmod +x script.sh   # Otorga permiso de ejecución
./script.sh          # Ejecuta directamente

Así el kernel leerá el #! y usará el intérprete indicado.

2) Verificar la transmisión de argumentos

Ejemplo:

#!/usr/bin/env bash

echo "Intérprete: $0"
echo "Argumentos: $@"

Ejecuta:

chmod +x test.sh
./test.sh hello world

Salida:

Intérprete: ./test.sh
Argumentos: hello world

$0 es la ruta del propio script; el kernel realmente ejecuta algo como /usr/bin/env bash test.sh hello world.


8. Mitos comunes

“La primera línea es solo un comentario, ¿puedo omitirla?”

  • Sí, no es obligatoria.
  • Si ejecutas el script con bash myscript.sh o python3 myscript.py, el shebang se ignora.
  • Pero si quieres ejecutar el script con ./myscript.sh, necesitas el shebang.

“¿Puedo usar #!/bin/env en lugar de #!/usr/bin/env?”

  • Algunos sistemas tienen /bin/env, pero usr/bin/env es el estándar más universal.
  • Si no hay una razón específica, usa #!/usr/bin/env ….

9. Resumen

  • #!/usr/bin/env bash y #!/bin/bash no son comentarios; son instrucciones para el kernel sobre qué intérprete usar.
  • #!/bin/bash siempre usa /bin/bash → predecible pero menos portable.
  • #!/usr/bin/env bash busca bash en el PATH → más flexible y portable, pero depende del PATH.
  • En la mayoría de los entornos de desarrollo y despliegue, se recomienda usar #!/usr/bin/env bash.

image of shebang in linux script