Cuando escribimos programas de shell, solemos utilizar /bin/sh
y /bin/bash
. Yo suelo usar bash
, pero no sé cuál es la diferencia entre ellos.
¿Cuál es la principal diferencia entre bash
y sh
?
¿Qué debemos tener en cuenta al programar en bash
y sh
?
sh
(o Shell Command Language) es un lenguaje de programación descrito por el POSIX
standard.
Tiene muchas implementaciones (ksh88
, dash
, ...). bash
también puede ser
una implementación de sh
(ver más abajo).
Como sh
es una especificación, no una implementación, /bin/sh
es un enlace simbólico
(o un enlace duro) a una implementación real en la mayoría de los sistemas POSIX.
bash
comenzó como una implementación compatible con sh
(aunque es anterior al estándar POSIX por unos años), pero con el paso del tiempo ha adquirido muchas extensiones. Muchas de estas extensiones pueden cambiar el comportamiento de los scripts de shell POSIX válidos, así que por sí mismo bash
no es un shell POSIX válido. Más bien, es un dialecto del lenguaje de shell POSIX.
bash
soporta la opción --posix
, que lo hace más compatible con POSIX. También intenta imitar a POSIX si se invoca como sh
.
Durante mucho tiempo, /bin/sh
solía apuntar a /bin/bash
en la mayoría de los sistemas GNU/Linux. Como resultado, casi se había vuelto seguro ignorar la diferencia entre los dos. Pero esto ha empezado a cambiar recientemente.
Algunos ejemplos populares de sistemas en los que /bin/sh
no apunta a /bin/bash
(y en algunos de los cuales /bin/bash
ni siquiera existe) son:
sh
con dash
por defecto;initramfs
. Utiliza la implementación del shell ash
.pdksh
, un descendiente del shell Korn. El sh
de FreeBSD es un descendiente del shell Bourne original de UNIX. Solaris tiene su propio sh
que durante mucho tiempo no fue compatible con POSIX; hay una implementación libre disponible en el proyecto Heirloom.¿Cómo puede averiguar a qué apunta /bin/sh
en su sistema?
La complicación es que /bin/sh
puede ser un enlace simbólico o un enlace duro.
Si es un enlace simbólico, una forma portable de resolverlo es:
% file -h /bin/sh
/bin/sh: symbolic link to bash
Si es un enlace duro, intente
% find -L /bin -samefile /bin/sh
/bin/sh
/bin/bash
De hecho, la bandera -L
cubre tanto los enlaces simbólicos como los duros,
pero la desventaja de este método es que no es portable -
POSIX no requiere find
para soportar la opción -samefile
,
aunque tanto GNU find como FreeBSD find la soportan.
En última instancia, es usted quien decide cuál usar, escribiendo la línea "shebang".
Por ejemplo
#!/bin/sh
utilizará sh
(y lo que sea que apunte),
#!/bin/bash
usará /bin/bash
si está disponible (y fallará con un mensaje de error si no lo está). Por supuesto, también puedes especificar otra implementación, por ejemplo
#!/bin/dash
Para mis propios scripts, prefiero sh
por las siguientes razones:
bash
, se requiere que tengan `shUsar bash
también tiene sus ventajas. Sus características hacen que la programación sea más cómoda y similar a la de otros lenguajes de programación modernos. Esto incluye cosas como las variables locales de alcance y las matrices. El lenguaje sh
simple es un lenguaje de programación muy minimalista.
sh
: http://man.cx/sh
bash
: http://man.cx/bash
TL;DR: bash
es un superconjunto de sh
con una sintaxis más elegante y más funcionalidad. Es seguro utilizar una línea shebang de bash en casi todos los casos, ya que es bastante omnipresente en las plataformas modernas.
Nota: en algunos entornos, sh
es bash
. Comprueba sh --version
.
El Shell es una interfaz entre un usuario y el sistema operativo para acceder a los servicios de un sistema operativo. Puede ser una interfaz gráfica de usuario o una interfaz de línea de comandos (CLI).
sh (Bourne shell) es un intérprete de línea de comandos de shell, para sistemas operativos tipo Unix/Unix. Proporciona algunos comandos incorporados. En el lenguaje de scripting denotamos al intérprete como #!/bin/sh
. Fue uno de los más ampliamente soportados por otros shells como bash (libre/abierto), kash (no libre).
Bash (Bourne again shell) es un reemplazo del shell Bourne. Bash es un superconjunto de sh. Bash es compatible con sh. POSIX es un conjunto de estándares que definen cómo deben funcionar los sistemas compatibles con POSIX. Bash no es realmente un shell compatible con POSIX. En un lenguaje de scripting denotamos al intérprete como #!/bin/bash
.
Analogía: