¿Cuál es el shebang Bash preferido ("#!")?
¿ Existe algún Bash
asunto objetivamente mejor que los demás para la mayoría de los usos?
#!/usr/bin/env bash
#!/bin/bash
#!/bin/sh
#!/bin/sh -
- etc.
Recuerdo vagamente haber escuchado hace mucho tiempo que agregar un guión al final impide que alguien pase un comando a su script, pero no puedo encontrar ningún detalle al respecto.
Deberías usar #!/usr/bin/env bash
para portabilidad : Diferentes *nixes colocados bash
en diferentes lugares, y usarlos /usr/bin/env
es una solución alternativa para ejecutar el primero bash
que se encuentra en el archivo PATH
.
Y sh
no lo esbash
.
En la mayoría de los sistemas, pero no en todos, recomiendo usar:
#!/bin/bash
No es 100% portátil (algunos sistemas se ubican bash
en una ubicación distinta a /bin
), pero el hecho de que muchos scripts existentes lo utilicen #!/bin/bash
presiona a varios sistemas operativos para crear /bin/bash
al menos un enlace simbólico a la ubicación principal.
La alternativa de:
#!/usr/bin/env bash
Se ha sugerido, pero no hay garantía de que el env
comando esté activado /usr/bin
(y he usado sistemas en los que no lo está). Además, este formulario utilizará la primera instancia de bash
en el usuario actual $PATH
, que podría no ser una versión adecuada del shell Bash.
(Pero /usr/bin/env
debería funcionar en cualquier sistema razonablemente moderno, ya sea porque env
está disponible /usr/bin
o porque el sistema hace algo para que funcione. El sistema al que me referí anteriormente era SunOS 4, que probablemente no he usado en unos 25 años).
Si necesita que una secuencia de comandos se ejecute en un sistema que no tiene /bin/bash
, puede modificar la secuencia de comandos para que apunte a la ubicación correcta (eso, ciertamente, es un inconveniente).
He analizado las compensaciones con mayor profundidad en mi respuesta a esta pregunta .
Una actualización un tanto oscura: un sistema que uso, Termux , una capa similar a Linux de escritorio que se ejecuta bajo Android, no tiene /bin/bash
( bash
es /data/data/com.termux/files/usr/bin/bash
), pero tiene un manejo especial que admitir #!/bin/bash
.
ACTUALIZACIÓN: Como señala Edward L. en un comentario, bash no es parte del "SO base" en FreeBSD, e incluso si está instalado de forma predeterminada, probablemente no se instalará como /bin/bash
. En un sistema de este tipo, puedes usar el #!/usr/bin/env
truco (supongo que FreeBSD se instaló env
como /usr/bin/env
), o puedes usar la ruta donde está instalado bash (aparentemente es #!/usr/local/bin/bash
). Si sus scripts solo están destinados a ejecutarse en FreeBSD, puede utilizar #!/usr/local/bin/bash
. Si están destinados a ser portátiles, puede usar el #!/usr/bin/env
truco (que tiene algunas desventajas; consulte mi respuesta citada anteriormente) o puede actualizar la #!
línea cuando instale sus scripts.
Es posible que existan problemas similares en otros sistemas operativos.
/bin/sh
Generalmente es un enlace al shell predeterminado del sistema, que a menudo es, bash
pero en, por ejemplo, los sistemas Debian son más livianos dash
. De cualquier manera, el shell Bourne original es sh
, por lo que si su script usa algunas bash
características específicas (segunda generación, "Bourne Again sh") ( [[ ]]
pruebas, matrices, varias cosas azucaradas, etc.), entonces debería ser más específico y usar el último. . De esta manera, en sistemas donde bash no está instalado, su script no se ejecutará. Entiendo que puede haber una emocionante trilogía de películas sobre esta evolución... pero eso podría ser un rumor.
También tenga en cuenta que cuando se evoca como sh
, bash
hasta cierto punto se comporta como el estándar POSIX sh
(consulte también los documentos de GNU sobre esto).
Usar una línea shebang para invocar al intérprete apropiado no es solo para BASH. Puede utilizar shebang para cualquier lenguaje interpretado en su sistema, como Perl, Python, PHP (CLI) y muchos otros. Por cierto, el asunto
#!/bin/sh -
(También pueden ser dos guiones, es decir --
) finaliza las opciones de bash. Todo lo que sigue será tratado como nombres de archivos y argumentos.
El uso del env
comando hace que su secuencia de comandos sea portátil y le permite configurar entornos personalizados para su secuencia de comandos, por lo que se deben usar secuencias de comandos portátiles.
#!/usr/bin/env bash
O para cualquier idioma, como Perl.
#!/usr/bin/env perl
Asegúrese de mirar las man
páginas para bash
:
man bash
y env
:
man env
Nota: En Debian y en sistemas basados en Debian, como Ubuntu, sh
está vinculado a dash
no bash
. Como utilizan todos los scripts del sistema sh
. Esto permite que bash crezca y que el sistema se mantenga estable, según Debian.
Además, para mantener la invocación *nix como nunca uso extensiones de archivo en scripts invocados por shebang, ya que no se puede omitir la extensión en la invocación en ejecutables como se puede hacer en Windows. El comando de archivo puede identificarlo como un script.