Pregunta sobre shebang, bash – ¿Cuál es el Bash Shebang preferido?

904

Hay algunaBash ¿Shebang objetivamente mejor que los otros para la mayoría de los usos?

#!/usr/bin/env bash#!/bin/bash#!/bin/sh#!/bin/sh -etc

Recuerdo vagamente que hace mucho tiempo escuché que agregar un guión al final impide que alguien pase un comando a su script, pero no puede encontrar ningún detalle al respecto.

Y es/usr/local/bin/bash en OpenBSD. jww

Tu respuesta

5   la respuesta
7

Recomiendo usar:

<code>#!/bin/bash
</code>

No es 100% portátil (algunos sistemas colocanbash en un lugar que no sea/bin), pero el hecho de que muchos de los scripts existentes usan#!/bin/bash presiona varios sistemas operativos para hacer/bin/bash al menos un enlace simbólico a la ubicación principal.

La alternativa de:

<code>#!/usr/bin/env bash
</code>

ha sido sugerido, pero no hay garantía de que elenv el comando está en/usr/bin (Y he usado sistemas donde no lo es). Además, este formulario utilizará la primera instancia debash en los usuarios actuales$PATH, lo que podría no ser una versión adecuada de la shell bash.

Si necesita una secuencia de comandos para ejecutar en un sistema que no tiene/bin/bash, puede modificar la secuencia de comandos para que apunte a la ubicación correcta (lo que es un inconveniente).

He discutido las compensaciones en mayor profundidad enmi respuesta aesta pregunta.

17

El uso de una línea shebang para invocar al intérprete apropiado no es solo para BASH. Puede usar el shebang para cualquier lenguaje interpretado en su sistema, como Perl, Python, PHP (CLI) y muchos otros. Por cierto, el shebang

<code>#!/bin/sh -
</code>

(También puede ser dos guiones, es decir,--) finaliza las opciones de bash todo después serán tratados como nombres de archivo y argumentos.

Utilizando laenv el comando hace que su script sea portátil y le permite configurar entornos personalizados para su script, por lo tanto, los scripts portátiles deberían usar

<code>#!/usr/bin/env bash
</code>

O para cualquiera que sea el idioma como Perl

<code>#!/usr/bin/env perl
</code>

Asegúrate de mirar elman páginas parabash:

<code>man bash
</code>

yenv:

<code>man env
</code>

Nota: en sistemas basados ​​en Debian y Debian, como Ubuntu,sh está vinculado adash nobash. Como todos los scripts del sistema usansh. 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 los scripts invocados shebang, ya que no puede omitir la extensión en la invocación en ejecutables como puede hacerlo en Windows. El comando de archivo puede identificarlo como un script.

1231

Deberías usar#!/usr/bin/env bash paraportabilidad: diferente * nixes putbash en diferentes lugares, y utilizando/usr/bin/env es una solución para ejecutar el primerbash encontrado en elPATH. Ysh no esbash.

Que idioma essh? Kolob Canyon
@darkfeline La portabilidad no es absoluta, es matemáticamente imposible crear un script que haga lo mismo en todas las plataformas. Desde 2012 hasta 2018/usr/bin/env existe en más máquinas que cualquiera de/bin/bash xor/usr/bin/bash, así que un script que comienza con esta líneahacer lo esperado en tantas máquinas como sea posible. l0b0
@ I0b0 Hará lo esperado.Si tengo la versión correcta en mi camino.. No puedo especificar que mi script necesitabash 4.2 o posterior utilizando un shebang; Sólo puedo documentar ese requisito. Realmente, el guionista no debería ser el que controla el shebang; debe ser la personacorriendo la secuencia de comandos. Python hace esto bien, IMO: uso de scripts#!python, y el instalador lo reemplaza con el shebang correcto para el sistema de destino. chepner
@ l0b0 En realidad, la portabilidad puede ser absoluta bajo POSIX. Suponiendo que, por supuesto, que Bash está en la ruta, puede usar un script comoesta. Un archivo ejecutable sin un shebang y que no coincida con un formato ejecutable binario se ejecuta con sh. Esto es totalmente portátil bajo POSIX, a diferencia de esta respuesta. (Lo siento por el doble comentario, la edición de comentarios estúpidos de StackOverflow.) darkfeline
68

/bin/sh suele ser un enlace al shell predeterminado del sistema, que a menudo esbash pero en, por ejemplo, los sistemas Debian son los más ligerosdash. De cualquier manera, el shell original de Bourne essh, entonces si tu script usa algobash (2ª generación, "Bourne Again sh") características específicas ([[ ]] pruebas, arrays, varias cosas azucaradas, etc.), entonces debería ser más específico y usar lo siguiente. De esta manera, en los sistemas donde no está instalado bash, su script no se ejecutará. Entiendo que puede haber una trilogía emocionante de películas sobre esta evolución ... pero eso podría ser un rumor.

También tenga en cuenta que cuando se evoca comosh, bash hasta cierto puntose comporta como el estándar POSIX sh (ver tambiénlos documentos de GNU sobre esto).

"Puedo escribir a toda velocidad por media milla antes de que mis manos empiecen a temblar". xdhmoore
La mayoría de los sistemasno enlazar/bin/sh a cualquier lugar en/usr ya que eso haría que sea bastante difícil que los scripts de inicio se ejecuten antes/usr esta montado. aij
@aij No sé por qué puse "muchos o la mayoría" allí. Soy un usuario de fedora, donde/bin y/sbin Durante años solo hemos sido enlaces simbólicos por defecto, para/usr/bin y/usr/sbin, entonces en ese contexto/bin/sh es un enlace abash y el directorio actual es/usr/bin. Pero voy a corregir lo anterior. delicateLatticeworkFever
El dominio público Korn Shell (pdksh) está predeterminado en OpenBSD. jww
3

Realmente depende de cómo escribas tus scripts de bash. Si tu/bin/sh tiene un enlace simbólico a bash, cuando bash se invoca comosh, algunas características no están disponibles.

Si desea funciones específicas de bash que no sean POSIX, use#!/bin/bash

Bash no está instalado en OpenBSD. Si lo instalas víapkg_add, luego se ubica en/usr/local/bin, que puede no estar en ruta. jww

Preguntas relacionadas