read - bash script variables
¿Por qué#!/Usr/bin/env bash es superior a#!/Bin/bash? (4)
He visto en varios lugares, incluidas las recomendaciones en este sitio ( ¿Cuál es el shenb Bash preferido? ), Utilizar #!/usr/bin/env bash
en lugar de #!/bin/bash
. Incluso he visto a un individuo emprendedor que sugiere utilizar #!/bin/bash
y que la funcionalidad de bash se perderá al hacerlo.
Dicho todo esto, utilizo Bash en un entorno de prueba estrictamente controlado donde cada unidad en circulación es esencialmente un clon de una sola unidad maestra. Entiendo el argumento de la portabilidad, aunque no es necesariamente aplicable en mi caso. ¿Hay alguna otra razón para preferir #!/usr/bin/env bash
a las alternativas y, asumiendo que la portabilidad era una preocupación, ¿hay alguna razón para usarla que podría romper la funcionalidad?
Hay muchos sistemas que no tienen Bash in /bin
, FreeBSD y OpenBSD solo por nombrar algunos. Si su secuencia de comandos está destinada a ser portátil para muchos Unices diferentes, es posible que desee utilizar #!/usr/bin/env bash
lugar de #!/bin/bash
.
Tenga en cuenta que esto no es cierto para sh
; para scripts que cumplen con Bourne utilizo exclusivamente #!/bin/sh
, ya que creo que casi todos los Unix existentes tienen sh
in /bin
.
La ubicación estándar de bash es /bin
, y sospecho que eso es cierto en todos los sistemas. Sin embargo, ¿qué pasa si no te gusta esa versión de bash? Por ejemplo, quiero usar bash 4.2, pero el bash en mi Mac está en 3.2.5.
Podría intentar reinstalar bash en /bin
pero puede ser una mala idea. Si actualizo mi sistema operativo, se sobrescribirá.
Sin embargo, podría instalar bash en /usr/local/bin/bash
, y configurar mi RUTA en:
PATH="/usr/local/bin:/bin:/usr/bin:$HOME/bin"
Ahora bien, si especifico bash
, no obtengo el viejo cruddy en /bin/bash
, pero el más nuevo y brillante en /usr/local/bin
. ¡Bonito!
¡Excepto que mis scripts de shell tienen eso !# /bin/bash
shebang. Por lo tanto, cuando ejecuto mis scripts de shell, obtengo esa versión vieja y pésima de bash que ni siquiera tiene matrices asociativas.
Usar /usr/bin/env bash
usará la versión de bash encontrada en mi PATH. Si configuro mi RUTA, para que se ejecute /usr/local/bin/bash
, ese es el bash que usarán mis scripts.
Es raro ver esto con bash, pero es mucho más común con Perl y Python:
- Algunas versiones de Unix / Linux que se centran en la estabilidad a veces se quedan atrás con el lanzamiento de estos dos lenguajes de scripting. No hace mucho, el Perl de RHEL estaba en 5.8.8, ¡una versión de Perl de ocho años de antigüedad! Si alguien quería usar funciones más modernas, debe instalar su propia versión.
- Programas como Perlbrew y Pythonbrew le permiten instalar múltiples versiones de estos idiomas. Dependen de las secuencias de comandos que manipulan su RUTA para obtener la versión que desea. Codificar duro el camino significa que no puedo ejecutar mi script bajo preparación .
- No fue hace tanto tiempo (bueno, fue hace mucho tiempo) que Perl y Python no eran paquetes estándar incluidos en la mayoría de los sistemas Unix. Eso significaba que no sabías dónde se instalaron estos dos programas. ¿Estaba en
/bin
?/usr/bin
?/opt/bin
? ¿Quién sabe? Usando#! /usr/bin/env perl
#! /usr/bin/env perl
significaba que no tenía que saberlo.
¡Y ahora por qué no debes usar #! /usr/bin/env bash
#! /usr/bin/env bash
Cuando el camino está codificado en el shebang, tengo que correr con ese intérprete. Por lo tanto, #! /bin/bash
#! /bin/bash
me obliga a utilizar la versión predeterminada instalada de bash. Como las características de bash son muy estables (intente ejecutar una versión 2.x de una secuencia de comandos Python bajo Python 3.x) es muy poco probable que mi script BASH particular no funcione, y dado que mi script bash probablemente sea utilizado por este sistema y otros sistemas , el uso de una versión no estándar de bash puede tener efectos no deseados. Es muy probable que quiera asegurarme de que la versión estándar estable de bash se use con mi script de shell. Por lo tanto, probablemente quiera codificar el camino en mi shebang.
Para invocar bash
es un poco exagerado. A menos que tenga múltiples binarios bash
como el suyo en ~ / bin, pero eso también significa que su código depende de que $ PATH tenga las cosas correctas.
Sin embargo, es útil para cosas como python
. Hay scripts y entornos de envoltura que conducen a binarios alternativos de python
.
Pero no se pierde nada al usar la ruta exacta al binario, siempre y cuando esté seguro de que es el binario que realmente desea.
#!/usr/bin/env
busca PATH
para bash
, y bash
no siempre está en /bin
, particularmente en sistemas que no son Linux. Por ejemplo, en mi sistema OpenBSD, está en /usr/local/bin
, ya que se instaló como un paquete opcional.
Si está absolutamente seguro de que bash
está en /bin
y siempre lo estará, no hay nada de malo en ponerlo directamente en su shebang, pero recomendaría que no lo haga porque los scripts y los programas tienen vidas más allá de lo que inicialmente creemos que tendrán.