Saltar al contenido

¿Cuándo debo usar #! / Bin / bash y cuándo #! / Bin / sh?

Solución:

En breve:

  • Hay varios shells que implementan un superconjunto de la especificación sh de POSIX. En diferentes sistemas, /bin/sh podría ser un enlace a ash, bash, dash, ksh, zsh, & c. (Sin embargo, siempre será compatible con sh, nunca con csh o fish).

  • Siempre y cuando te ciñas a sh solo funciones, puede (y probablemente incluso debería) usar #!/bin/sh y 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 específicamente bash, porque, incluso si /bin/sh ya invoca bash en tu sistema, puede que no esté encendido todos los demás system, y su script no se ejecutará allí. (Por supuesto, lo mismo se aplica a zsh y ksh). Puede usar shellcheck para identificar bashismos.

  • Incluso si el script es solo para uso personal, es posible que observe que algunos sistemas operativos cambian /bin/sh durante las actualizaciones, por ejemplo, en Debian solía ser bash, pero luego fue reemplazado por un guión mínimo. Scripts que usaban bashismos pero tenían #!/bin/sh de repente se rompió.

Sin embargo:

  • Incluso #!/bin/bash no es muy correcto. En diferentes sistemas, bash puede vivir en /usr/bin o /usr/pkg/bin o /usr/local/bin.

  • Una opción más confiable es #!/usr/bin/env bash, que usa $ PATH. (Aunque el env la herramienta en sí tampoco está estrictamente garantizada, /usr/bin/env todavía funciona en más sistemas que /bin/bash lo hace.)

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, dado que no ha usado matrices (o lo que sea bash característica que conoce), puede elegir con seguridad 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.

Considere esto: si se va #!/bin/bash y sus usuarios no lo tienen, verán un mensaje de error claro, algo como

Error: /bin/bash not found

La mayoría de los usuarios pueden solucionar este problema en menos de un minuto instalando el paquete adecuado. Por otro lado, si reemplaza el shebang por #!/bin/sh y probarlo en un sistema donde /bin/sh es un enlace simbólico a /bin/bash, tus 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á ni idea de qué shell deberían haber utilizado.

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. Otro 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 script a fondo con el shell de destino, luego cambie el shebang.

Solo deberías usar #! /bin/sh.

Nunca debe usar extensiones bash (o zsh, o fish, o …) en un script de shell.

Solo debe escribir scripts de shell que funcionen con alguna implementación del lenguaje shell (incluidos todos los programas de “utilidad” que acompañan al propio shell). Estos dias tu puedes probablemente tomar POSIX.1-2001 (no -2008) como autoridad para lo que el shell y las utilidades son capaces de hacer, pero tenga en cuenta que algún día puede ser llamado a portar 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 a su favor es que /bin/sh es el único intérprete de guiones que cada Se garantiza que la instalación de Unix tiene.

Aquí está la otra cosa: alguna iteración del intérprete central de Perl 5 (/usr/bin/perl) es más probablemente esté disponible en una instalación 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 cuando los compare con shell) también están aproximadamente tan disponibles como bash y otros shells extendidos.

Por lo tanto, si tiene la opción de escribir un script bash, tienes la opción de usar un lenguaje de programación que no sea terrible.

Ahora, sencillo scripts de shell, del tipo que solo ejecutan 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 matrices o funciones o [[ incluso. Y solo deberías escribir Complicado scripts de shell cuando no tenga otra opción. Los scripts de Autoconf, por ejemplo, siguen siendo scripts de shell. Pero esos scripts tienen que ejecutarse cada 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 viejos Unix propietarios en estos días, pero probablemente deberían se preocupan por los BSD de código abierto actuales, algunos de los cuales no se instalan bash de forma predeterminada, y entornos integrados que le brindan solo un shell mínimo y busybox.

En conclusión, en el momento en que te encuentres falto 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, vuelva a escribirlo en un idioma mejor.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *