¿Cuándo es #!/bin/bashmás apropiado que #!/bin/shen un script de shell?
                    
                        linux
                                shell-script
                                
                    
                    
                        Hendré
fuente
                
                fuente

bashfunciones y sintaxis en lugar deshfunciones y sintaxis.vimresaltarábash-ismos si su script tiene el#!/bin/shshebang. Solo lo cambio abashsi las cosas se ponen lo suficientemente peludas como para comenzar a necesitar funciones bash.$(...)Es particularmente desagradable. Además, algunos de ellos son sutiles [<(...)ycmd >& fileno reciben ningún resaltado de error, por ejemplo, simplemente no tienen resaltado especial para lo que quieren decir, con o sing:is_bash]Respuestas:
En breve:
Hay varios shells que implementan un superconjunto de la especificación POSIX sh . En diferentes sistemas,
/bin/shpuede haber un enlace a ash, bash, dash, ksh, zsh, & c. (Sin embargo, siempre será compatible con sh, nunca csh o fish).Siempre y cuando se limite a las
shcaracterísticas solamente, puede (y probablemente incluso debería) usar#!/bin/shy el script debería funcionar bien, sin importar de qué shell se trate.Si comienza a usar características específicas de bash (por ejemplo, matrices), debe solicitar específicamente bash, porque, incluso si
/bin/shya invoca bash en su sistema, puede que no esté en el sistema de todos los demás , y su script no se ejecutará allí. (Lo mismo, por supuesto, se aplica a zsh y ksh). Puede usar shellcheck para identificar bashisms.Incluso si el script es solo para uso personal, puede notar que algunos sistemas operativos cambian
/bin/shdurante las actualizaciones, por ejemplo, en Debian solía ser bash, pero luego se reemplazó con un guión muy mínimo. Guiones que usaban bashismos pero que de#!/bin/shrepente se habían roto.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 laenvherramienta en sí tampoco está estrictamente garantizada,/usr/bin/envaún funciona en más sistemas que/bin/bash).fuente
/bin/shentonces, intentará imitarshcaracterísticas (ver página de manual ), no estoy seguro de que las características específicas de bash estén disponibles en este modo.envtool es una herramienta posix , debería encontrarse en la mayoría de las distribuciones, pero no estoy seguro, ya que algunos pueden no respetar posix./bin: " Las aplicaciones deben tener en cuenta que la RUTA estándar al shell no se puede suponer que sea / bin / sh o / usr / bin / sh, y se debe determinar mediante la interrogación de la RUTA devuelta por getconf RUTA, asegurando que la ruta devuelta sea una ruta absoluta y no un shell incorporado ". También vea esta pregunta y, específicamente, esta respuesta .#!funcionen los scripts?echo foo ^ catemitefoo ^ caten POSIX sh, y emite solofooen Bourne (como^es un carácter de tubería allí).Use el shebang correspondiente al shell que realmente utilizó 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 las matrices ya que no se ha utilizado (o cualquierbashcaracterística que está consciente de), que está seguro de escoger cualquier cáscara te gusta. Hay muchas diferencias sutiles entre los shells (echofunciones, bucles, lo que sea) que no se pueden descubrir sin una prueba adecuada.Considere esto: si se va
#!/bin/bashy sus usuarios no lo tienen, verán un mensaje de error claro, algo así comoLa 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/shy lo prueba en un sistema donde/bin/shhay un enlace simbólico/bin/bash, sus usuarios que no lo tenganbashestarán en problemas. Lo más probable es que vean un mensaje de error críptico como:Esto puede tomar horas para solucionarlo, y no habrá idea sobre qué shell deberían haber utilizado.
No hay muchas razones por las que quieras usar un shell diferente en el shebang. Una razón es cuando el caparazón que ha utilizado no está muy extendido. Otra es ganar rendimiento con el
shcual es significativamente más rápido en algunos sistemas, Y su script será un cuello de botella de rendimiento. En ese caso, pruebe su script a fondo con el shell de destino, luego cambie el shebang.fuente
Solo deberías usarlo alguna vez
#! /bin/sh.No debe usar extensiones bash (o zsh, o fish, o ...) en un script de shell, nunca.
Solo debe escribir scripts de shell que funcionen con cualquier implementación del lenguaje de shell (incluidos todos los programas de "utilidad" que acompañan al propio shell). En estos días, probablemente pueda 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 para portar su script a un sistema heredado (por ejemplo, Solaris o AIX) cuyo shell y utilidades fueron congelados alrededor de 1992
¿Qué, en serio?
Sí, en serio.
Aquí está la cosa: Shell es un lenguaje de programación terrible . Lo único que tiene es que
/bin/shes el único intérprete de guiones que se garantiza que todas las instalaciones de Unix tengan.Aquí está la otra cosa:
/usr/bin/perles más probable que alguna iteración del intérprete principal de Perl 5 ( ) esté disponible en una instalación de Unix seleccionada al azar de lo que(/(usr|opt)(/(local|sfw|pkg)?)?/bin/bashestá. Otros buenos lenguajes de scripting (Python, Ruby, node.js, etc. - Incluso incluiré PHP y Tcl en esa categoría al comparar con shell) también están 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 sea terrible.
Ahora, simples scripts de shell, del tipo que solo 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 matrices o funciones, ni
[[siquiera. Y solo debe escribir scripts de shell complicados cuando no tiene otra opción. Las secuencias de comandos de Autoconf, por ejemplo, siguen siendo correctamente secuencias de comandos de shell. Pero esos scripts tienen que ejecutarse en cada encarnación/bin/shque sea 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 patentados en estos días, pero probablemente debería preocuparse por los BSD de código abierto actuales, algunos de los cuales no se instalanbashde forma predeterminada, y entornos integrados que le brindan solo un shell y un mínimobusybox.En conclusión, en el momento en que te encuentras queriendo una característica que no está disponible en el lenguaje shell portátil, eso es una señal de que el script se ha vuelto demasiado complicado para seguir siendo un script shell. Reescríbalo en un mejor idioma.
fuente
sh. Eso, sin embargo, está muy lejos de afirmar que nunca debes usar otros proyectiles. Hay miles (probablemente muchos más) scripts escritos todos los días y la gran mayoría de ellos solo se ejecutarán en una sola máquina. Su consejo tiene sentido en el código de producción, pero no para los trabajos diarios de "sysdaminy" para los que se escriben la mayoría de los scripts. Si sé que mi script solo será utilizado por mí y en una máquina Linux, bash está bien.En general, si el tiempo es más importante que la funcionalidad, usará el shell más rápido. sh a menudo tiene el alias de guión y tiende a usarse para tareas cron de root u operaciones por lotes donde cada (nano) segundo cuenta.
fuente
Para ser aún más breve, use
shsi la portabilidad en la mayoría de los sistemas es lo más importante ybashsi desea usar algunas de sus características específicas, como los arreglos, si la versión de bash lo admite.fuente
El camino más seguro. cuando está codificado, sería / usr / bin /
shellOfChoicepero una nueva convención que trato de usar siempre ahora, ya que las 'ubicaciones predeterminadas' a través de un cambio PATH pueden cambiar es:#! / usr / bin / env sh o
#! / usr / bin / env bash
o, por ejemplo, scripts perl
#! / usr / bin / env perl -w
Por supuesto, cuando tiene una razón para que un script NUNCA tome una nueva RUTA automáticamente, continúe teniendo un código rígido, y luego / usr / bin / something debería ser la ruta más probable para usar.
fuente