¿Cuál es la diferencia entre #! / Bin / sh y #! / Bin / bash?

281

si yo escribo

#!/bin/bash
echo "foo"

o

#!/bin/sh
echo "foo"

ambos rinden lo mismo. He visto algunos guiones que comienzan con #!/bin/sho #!/bin/bash. ¿Hay alguna diferencia entre ellos?

Rahul Virpara
fuente

Respuestas:

242

bashy shson dos conchas diferentes. Básicamente bashes sh, con más funciones y mejor sintaxis. La mayoría de los comandos funcionan igual, pero son diferentes.

Dicho esto, debe darse cuenta de que /bin/shen la mayoría de los sistemas habrá un enlace simbólico y no invocará sh. En Ubuntu /bin/shsolía vincularse bash, comportamiento típico en las distribuciones de Linux, pero ahora ha cambiado a vincularse a otro shell llamado guión . Yo usaría bash, ya que es más o menos el estándar (o al menos el más común, desde mi experiencia). De hecho, surgen problemas cuando se usa un script bash #!/bin/shporque el creador del script asume que el enlace es bashcuando no tiene que ser así.

Para más información, http://man.cx/sh , http://man.cx/bash .

reverendj1
fuente
25
Su primer párrafo es bastante engañoso. "sh" no es un shell en absoluto, sino un enlace simbólico al shell del sistema configurado actualmente , que en los sistemas Linux suele ser bash o dash (versiones recientes de Ubuntu que utilizan este último).
thomasrutter
19
/bin/shsolía ser un shell llamado bourne shell en 1977. bash es un shell compatible con / bin / sh que se puede usar como un reemplazo del shell bourne que es conforme con posix. en.wikipedia.org/wiki/Bourne_shell
Alex
55
bash es un estándar de facto (muy utilizado) pero no es "estándar"; sh en Ubuntu usa dash , que es un shell compatible con Posix, por lo que es realmente estándar. Mi consejo es usar el guión tan a menudo como sea posible para las secuencias de comandos, especialmente para las secuencias de comandos del lado del servidor. Aunque bash es más expresivo, el tablero se ejecuta mucho más rápido y es más seguro.
Rick-777
@ Rick-777 Entonces, ¿debería poner explícitamente #! / Bin / dash en la parte superior de mis scripts? También he escrito guiones donde solo escribo comandos y los ejecuto con ./scriptName y eso ha funcionado bien. ¿Es necesario el #! / Bin / yourShellHere?
user137717
@ Rick-777 En los casos en que excluyo cualquier #! / Bin / shellName, he nombrado los archivos fileName.sh. ¿Se vinculará implícitamente con el shell del sistema preferido sin declarar #! / Bin / sh?
user137717
82

En Linux y otros sistemas similares a Unix, puede elegir entre varios shells.

El shell es responsable no solo de dibujar su pequeño aviso, sino también de interpretar sus comandos, especialmente si coloca una lógica complicada como tuberías, condicionales, etc.

bash es el shell más común utilizado como un shell predeterminado para usuarios de sistemas Linux. Es un descendiente espiritual de otros proyectiles utilizados a lo largo de la historia de Unix. Su nombre, bash es una abreviatura de Bourne-Again Shell, un homenaje al Bourne shell para el que fue diseñado para reemplazar, aunque también incorpora características de C Shell y Korn Shell.

Se ejecuta, en estos días, desde /bin/bash: cualquier sistema con bash lo tendrá accesible aquí.

Sin embargo, no solo los usuarios usan shells. Los scripts (scripts de shell ) necesitan shells para interpretarlos. Cuando ejecuta un script de shell, su sistema necesita iniciar un proceso de shell para ejecutar su script.

El problema es que diferentes shells tienen pequeñas inconsistencias entre ellos, y cuando se trata de ejecutar scripts, estos pueden ser un problema real. bash tiene muchas características de scripting que son exclusivas de bash y no de otros shells. Esto está bien, si siempre vas a usar bash para ejecutar esos scripts. Otros shells pueden intentar emular bash o adherirse al estándar POSIX, que bash admite bastante bien (aunque agrega sus propias extensiones).

Es posible especificar en la parte superior de un script de shell con qué shell se debe ejecutar usando un shebang. Un script puede especificar #!/bin/bashen la primera línea, lo que significa que el script siempre debe ejecutarse con bash, en lugar de otro shell.

/ bin / sh es un ejecutable que representa el shell del sistema . En realidad, generalmente se implementa como un enlace simbólico que apunta al ejecutable para cualquier shell que sea el shell del sistema. El shell del sistema es una especie de shell predeterminado que los scripts del sistema deberían usar. En las distribuciones de Linux, durante mucho tiempo esto fue generalmente un enlace simbólico a bash , tanto es así que se ha convertido en una convención siempre vincular / bin / sh a bash o un shell compatible con bash. Sin embargo, en los últimos años, Debian (y Ubuntu) decidieron cambiar el shell del sistema de bash a dash- un shell similar, rompiendo con una larga tradición en Linux (bueno, GNU) de usar bash para / bin / sh. Dash es visto como un shell más ligero y mucho más rápido que puede ser beneficioso para la velocidad de arranque (y otras cosas que requieren muchos scripts de shell, como los scripts de instalación de paquetes).

Dash es bastante compatible con bash, ya que se basa en el mismo estándar POSIX. Sin embargo, no implementa las extensiones específicas de bash. Existen scripts que usan #!/bin/sh(el shell del sistema) como shebang, pero que requieren extensiones específicas de bash. Actualmente, esto se considera un error que Debian y Ubuntu deben corregir, que requieren / bin / sh para poder funcionar cuando se apunta al guión.

Aunque el shell del sistema de Ubuntu apunta a dash, su shell de inicio de sesión como usuario continúa siendo bash en este momento. Es decir, cuando inicia sesión en un emulador de terminal en cualquier lugar de Linux, su shell de inicio de sesión será bash. La velocidad de operación no es tanto un problema cuando el shell se usa de forma interactiva, y los usuarios están familiarizados con bash (y pueden tener personalizaciones específicas de bash en su directorio de inicio).

Lo que debe usar al escribir scripts

Si su script requiere características que solo son compatibles con bash, use #!/bin/bash.

Pero si es posible, sería bueno asegurarse de que su script sea compatible con POSIX y utilizarlo #!/bin/sh, lo que siempre debe, de manera bastante confiable, apuntar al shell del sistema compatible con POSIX preferido en cualquier instalación.

thomasrutter
fuente
18

Además de las respuestas anteriores, incluso si /bin/shes un enlace simbólico a /bin/bash, #!/bin/shno es totalmente equivalente a #!/bin/bash.

Desde la página del comando man bash (1) :

"Si se invoca bash con el nombre sh, intenta imitar el comportamiento de inicio de las versiones históricas de sh lo más cerca posible, a la vez que se ajusta al estándar POSIX".

Por ejemplo, la sintaxis específica de bash:

 exec  > >(tee logfile.txt)

da un error en un shell que comienza con #!/bin/sh, incluso con el enlace simbólico sh-> bash en su lugar.

AnkiF
fuente
6

GNU Bash: #!/bin/bash; POSIX de Shell: #!/bin/sh.

山 茶树 和 葡萄 树
fuente
Bueno, respuesta corta pero precisa. 还 行
Sergiy Kolodyazhnyy