En resumen:
-
Hay varios shells que implementan un superconjunto de la especificación POSIX sh. En diferentes sistemas,
/bin/shpodría ser un enlace a ash, bash, dash, ksh, zsh, &c. (Sin embargo, siempre será compatible con sh, nunca csh o fish). -
Siempre y cuando te ciñas a
shsolo funciones, puede (y probablemente incluso debería) usar#!/bin/shy el script debería funcionar bien, sin importar qué shell sea. -
Si comienza a usar funciones específicas de bash (por ejemplo, matrices), debe solicitar bash específicamente, porque, incluso si
/bin/shya invoca bash en su sistema, puede que no esté en todos los demás sistema, y su secuencia de comandos no se ejecutará allí. (Por supuesto, lo mismo se aplica a zsh y ksh). Puede usar shellcheck para identificar bashisms. -
Incluso si la secuencia de comandos es solo para uso personal, es posible que observe que algunos sistemas operativos cambian
/bin/shdurante las actualizaciones, p. en Debian solía ser bash, pero luego fue reemplazado por un guión mínimo. Scripts que usaban bashisms pero tenían#!/bin/shse rompió de repente.
Sin embargo:
-
Incluso
#!/bin/bashno es muy correcto. En diferentes sistemas, bash podría vivir en/usr/bino/usr/pkg/bino/usr/local/bin. -
Una opción más confiable es
#!/usr/bin/env bash, que usa $PATH. (Aunque elenvla herramienta en sí tampoco está estrictamente garantizada,/usr/bin/envtodavía funciona en más sistemas que/bin/bashhace.)
Use el shebang correspondiente al shell que realmente usó para desarrollar y depurar su script. Es decir. si su shell de inicio de sesión es bash , y ejecuta su script como ejecutable en su terminal, use #!/bin/bash . No asuma que como no ha usado arreglos (o lo que sea bash característica que conoce), puede elegir el caparazón que desee. Hay muchas diferencias sutiles entre las conchas (echo , funciones, bucles, lo que sea) que no se pueden descubrir sin las pruebas adecuadas.
Considera esto:si dejas #!/bin/bash y sus usuarios no lo tienen, verán un claro mensaje de error, algo así como
Error: /bin/bash not found
La mayoría de los usuarios pueden arreglar esto en menos de un minuto instalando el paquete apropiado. Por otro lado, si reemplaza el shebang por #!/bin/sh y pruébelo en un sistema donde /bin/sh es un enlace simbólico a /bin/bash , sus usuarios que no tienen bash estará en problemas. Lo más probable es que vean un mensaje de error críptico como:
Error in script.sh line 123: error parsing token xyz
Esto puede tardar horas en solucionarse y no habrá ninguna pista sobre qué shell deberían haber usado.
No hay muchas razones por las que querrías usar un caparazón diferente en el shebang. Una razón es cuando el caparazón que ha utilizado no está muy extendido. Otra es ganar rendimiento con sh que es significativamente más rápido en algunos sistemas, Y su secuencia de comandos será un cuello de botella en el rendimiento. En ese caso, pruebe su secuencia de comandos a fondo con el shell de destino, luego cambie el shebang.
Solo deberías usar #! /bin/sh .
Nunca debe usar extensiones bash (o zsh, fish o ...) en un script de shell.
Solo debe escribir scripts de shell que funcionen con any implementación del lenguaje de shell (incluidos todos los programas de "utilidad" que acompañan al propio shell). En estos días puedes probablemente tomar POSIX.1-2001 (no -2008) como autorizado para lo que el shell y las utilidades son capaces de hacer, pero tenga en cuenta que algún día se le pedirá que transfiera su script a un sistema heredado (por ejemplo, Solaris o AIX) cuyo shell y utilidades se congelaron alrededor de 1992.
¡¿Qué, en serio?!
Sí, en serio.
Aquí está la cosa:Shell es un terrible lenguaje de programación. Lo único que tiene es que /bin/sh es el único intérprete de guiones que todos La instalación de Unix está garantizada.
Aquí está la otra cosa:alguna iteración del intérprete principal de Perl 5 (/usr/bin/perl ) es más probable que esté disponible en una instalación de Unix seleccionada al azar que (/(usr|opt)(/(local|sfw|pkg)?)?/bin/bash es. Otros buenos lenguajes de secuencias de comandos (Python, Ruby, node.js, etc.; incluso incluiré PHP y Tcl en esa categoría al compararlos con shell) también están tan disponibles como bash y otros shells extendidos.
Por lo tanto, si tiene la opción de escribir un script bash, tiene la opción de usar un lenguaje de programación que no es terrible, en su lugar.
Ahora, sencillo scripts de shell, del tipo que simplemente ejecuta algunos programas en una secuencia desde un trabajo cron o algo así, no hay nada de malo en dejarlos como scripts de shell. Pero los scripts de shell simples no necesitan arreglos o funciones o [[ incluso. Y solo debes escribir complicado scripts de shell cuando no tiene otra opción. Los scripts de Autoconf, por ejemplo, son correctamente scripts de shell. Pero esos scripts tienen que ejecutarse en todos encarnación de /bin/sh eso es relevante para el programa que se está configurando. y eso significa que no pueden usar ninguna extensión. Probablemente no tenga que preocuparse por los antiguos Unix propietarios en estos días, pero probablemente debería preocuparse por los BSD de código abierto actuales, algunos de los cuales no instalan bash de forma predeterminada, y entornos integrados que le brindan solo un shell mínimo y busybox .
En conclusión, el momento en que te encuentras queriendo una característica que no está disponible en el lenguaje de shell portátil, eso es una señal de que el script se ha vuelto demasiado complicado para seguir siendo un script de shell. En su lugar, reescríbalo en un idioma mejor.