En la mayoría de los scripts de shell que he visto (además de los que no he escrito yo mismo), noté que el shebang está configurado en #!/bin/sh
. Esto realmente no me sorprende en los scripts más antiguos, pero también está allí en scripts bastante nuevos.
¿Hay alguna razón para preferir /bin/sh
más /bin/bash
, ya que bash
es casi omnipresente, y con frecuencia por defecto, en muchas máquinas Linux y BSD que se remontan a más de una década?
/bin/sh
si no usabash
funciones específicas . Un día podría tener que usar uno de sus scripts en un sistema en el que no está instalado (servidor remoto, computadora integrada ...)...the answers so far are fairly subjective...
Una declaración "subjetiva" se basa esencialmente en la opinión por definición./bin/bash
solo debe usarse cuando bash es explícitamente necesario. En más de 40 años como desarrollador, mucho antesbash
, casi nunca lo necesitaba explícitamente , excepto durante las pruebas. (También me esfuerzo por evitar las extensiones de shell, pero la mayoría de mis scripts están destinados a la distribución). Muchos scripts en la red también deberían estar destinados a un uso amplio.Respuestas:
/bin
.fuente
/bin/sh
es más rápido si no es asíbash
, todavía hay algunos sistemas como OS / X o RHEL donde/bin/sh
estábash
./bin/sh
es/bin/bash
. El cambio de Ubuntu de bash a dash los rompió a todos.#!/bin/bash
si quisieran Bash (¡no hay nada de malo en eso!). El cambio se realizó principalmente en sentido ascendente en Debian. Mejoró la experiencia del usuario, tuvo un impacto medible en el tiempo de inicio del sistema. También afectó positivamente la seguridad, ver "Shellshock".La mayoría de los scripts del sistema en Linux (relacionado con Debian: Ubuntu, Mint, etc.) están escritos para ejecutarse en el tablero más rápido, que es el valor predeterminado / bin / sh en esos sistemas. La razón es doble:
Velocidad del sistema. Un código más pequeño de tablero se carga más rápido y también se ejecuta más rápido. Con algún (¿pequeño?) Esfuerzo adicional (costo) para los programadores de scripts de shell.
Seguridad. Tener diversidad de conchas ayuda a la resistencia a los insectos. Los sistemas Debian en su mayoría no eran vulnerables al shellshock porque el shell predeterminado no tenía esa vulnerabilidad.
Bash es el shell predeterminado para los usuarios , ya que es más potente y tiene muchos más elementos para facilitar la codificación. También es el predeterminado
sh
en Mac OS (el que está vinculado desde / bin / sh). Sin embargo, llamarbash
con el nombre del enlacesh
hace que comience como un shell compatible con posix.fuente
eval
, con la exposición de seguridad correspondiente; Del mismo modo, sin soporte incorporado expresiones regulares, uno puede necesitar usar comandos externos (a una penalización de rendimiento pesado) para hacer coincidir incluso dentro de una sola línea, etcOtros han señalado que las premisas de la pregunta, que el shell Bourne Again es predeterminado y omnipresente, son totalmente erróneas.
Además de eso, existen buenas razones para usar algo distinto del shell Bourne Again para interpretar los scripts del shell. Estas razones motivadas de Ubuntu y el gran proyecto de Debian, durante varios años, para eliminar del bash y hacer como muchos de los scripts de shell a cargo de la inicialización del sistema (que era una gran cantidad de secuencias de comandos shell con sistema 5
rc
) y la instalación de paquetes / uso eliminación del Shell de Debian Almquist en lugar del shell Bourne Again.En pocas palabras: el shell Bourne Again, repleto de características interactivas como es, no es el intérprete de shell más rápido para un script de shell compatible con POSIX. Entonces, si uno puede hacer que los scripts de shell sean compatibles con POSIX, interpretándolos con un programa más liviano, como el shell Debian Almquist, el sistema funcionará mejor. (Al final, Debian tuvo que hacer pequeños ajustes en el shell Almquist, para agregar soporte para un par de construcciones de shell que no son POSIX que simplemente estaban demasiado profundas y muy integradas y eran demasiado útiles para deshacerse de ellas).
El resultado de todo fue una gran ganancia en el rendimiento de arranque.
Entonces, hay dos clases distintas de shell para considerar, aquí:
Tenga en cuenta que hablar de esto como "preferir
/bin/sh
" es simplificar demasiado. Debian en realidad tenía al menos dos objetivos:Frente a los administradores que utilizan el shell Debian Almquist, el shell Z (en modo POSIX), el shell Bourne Again (en modo POSIX), el shell MirBSD Korn y otros
/bin/sh
, ya que había ...... haciendo que las secuencias de comandos sean lo más portátiles posible, de modo que cambiar lo
/bin/sh
mapeado no rompa las cosas; o... haciendo que los scripts no portátiles se dirijan explícitamente al programa de intérprete correcto , en lugar de simplemente esperar ese
/bin/sh
mapa.Hacía que el shell Debian Almquist fuera el mapeo predeterminado para
/bin/sh
Bourne Shell, de modo que los scripts que eran compatibles con POSIX (o, más adecuadamente, conformes con el Manual de políticas de Debian) se ejecutaban más rápidamente.Y, por supuesto, una vez que uno entra en esto, uno puede llevarlo mucho más lejos; como considerar las compensaciones de eficiencia de los gustos
/bin/true
y/usr/bin/clear
ser scripts de shell o programas compilados. Pero eso está más allá del alcance de esta respuesta, afortunadamente. ☺Nada de esto es muy nuevo, ni siquiera específico de Unix, por supuesto. Volver antes de la vuelta del siglo, escribí y publiqué un intérprete de línea de comandos que se incluye en ambos y sabores "interactivos" "no interactivos", que explica precisamente esta división en su mana y tomando nota de la diferencia entre las
COMSPEC
yOS2_SHELL
variables de entorno. Del mismo modo, la discusión sobre la eliminación de bashismos en el Sistema V de Debianrc
y los scripts de instalación / eliminación de paquetes se remontan a la década de 1990.Otras lecturas
/bin/sh
. Ubuntu wiki./bin/sh
. Wiki de Debian.fuente
Schily Bourne Shell
página de manual, ver schilytools.sourceforge.net/bosh.html son adecuados para permitir que las personas entiendan cómo escribir un script portátil (eso solo dependeBourne Shell features
de 1989). Lo que hice fue mencionar todas las mejoras que no estaban en los viejos Bourne Shells. Por cierto: también estoy interesado en conocer una lista de bashisms en el tablero.Si. La excelente respuesta de @ Marco lo describe bien.
Al escribir sus propios guiones, debe señalar el shebang a la cosa más general que ha probado.
En mi sistema (Centos 6.6),
sh
está vinculado abash
:Esto significa que siempre lo uso
#!/bin/bash
en mi shebang a menos que haya verificado que no tengo bashims en mi script.Al configurar el shebang,
#!/bin/sh
usted promete que el script funcionará con todas las implementaciones desh
.Esta es una promesa mucho más grande que decir que el script funcionará con bash.
Aquí hay un ejemplo de un script que se comportará incorrectamente según la
sh
implementación que esté utilizando el sistema:Al usar
bash
el script se imprimirá:Al usar
dash
el script se imprimirá:Si quiero usar,
#!/bin/sh
¿qué debo hacer?checkbashisms
- Tenga en cuenta que esto no encontrará todos los bashims. No encontró el bashism en mi guión arribash
implementación. Normalmentedash
pruebo con , sin embargo, espero que algunos bashisms o dashims todavía puedan pasar.La página DashAsBinSh en el wiki de Ubuntu tiene mucha información interesante.
fuente
/bin/sh
; solo los que cumplen con POSIX.La única razón restante para escribir un script de shell, en lugar de un script en un lenguaje más potente y ergonómico, es si la portabilidad a sistemas heredados con un conjunto desconocido de software instalado es más importante que cualquier otro factor .
/bin/sh
es el único intérprete de guiones que está disponible en todo lo que se llama a sí mismo Unix. Pero en una gran cantidad de sistemas heredados,/bin/sh
y las utilidades asociadas ni siquiera cumplen con la especificación POSIX.1-1996 "shell y utilidades", y mucho menos con algo más moderno. Las herramientas que cumplen con los estándares son un complemento opcional, instalado en/usr/xpg4
alguna ubicación no obvia. 1 Las secuencias de comandos en el lenguaje de shell del subconjunto portátil son aún más tediosas y propensas a errores que las secuencias de comandos en el lenguaje de shell POSIX. (Lea unconfigure
script generado por Autoconf en algún momento si no me cree. Solo la configuración debería ser suficiente para convencerlo).Pero si puede asumir que está instalado otro intérprete de script (por ejemplo, Bash), puede suponer que está instalado un intérprete para un mejor lenguaje de script . Perl, por ejemplo, es más probable que esté disponible que Bash.
Por lo tanto, nunca debe escribir un
#! /bin/bash
script, porque si esa es una opción, un mejor idioma también es una opción.1 Por ejemplo, Solaris 10 y anteriores enviaron el shell Bourne original como
/bin/sh
. Me informan que Solaris 11 lo actualizó a ksh93.fuente
/bin/sh
es POSIX.1-1996, sino que en realidad es un shell Bourne original de sintaxis previa a POSIX. Eso hace un shebang muy pobre para que los scripts se ejecuten con estos lanzamientos. Se utilizarían scripts portátiles en Solaris que no serán muy portátiles en otros sistemas operativos. En el último Solaris, Oracle Solaris 11 lanzado por primera vez en 2011, es un moderno que cumple con las especificaciones POSIX recientes y tiene muchas extensiones modernas.#!/bin/sh
#!/usr/xpg4/bin/sh
/bin/sh
ksh93
ash
que se proporciona con busybox), y tiendo a pensar que zwol tiene razón en que perl está más comúnmente disponible que bash.bash
está disponible, entonces es un mejor idioma, por lo que nunca debe escribir ningúnbash
código". Además, como señala @sixtyfootersdude, siempre debe usarlo a#!/bin/bash
menos que haya probado que su script funciona con cualquier shell POSIX.En realidad deberías estar usando cualquiera
o
de esa manera invocas a cualquiera de los shell por la forma en que se instalan en ese sistema.
Para ser súper seguro ( por ejemplo, en casos de reinicios de un solo usuario), use de
sh
otra manerabash
.fuente
the advantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH. The disadvantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH.
Esto probablemente también se aplica ash
ybash
.#!/bin/env
nada en un script portátil. Es perfectamente razonable suponer que/bin/sh
existe y que es un shell que funciona y cumple con POSIX. Por otro lado, ninguno de mis sistemas tiene un/bin/env
./bin/sh
. POSIX no lo requiere y define otras reglas para obtener un entorno compatible con POSIX en una plataforma certificada POSIX./usr/bin/env
no está universalmente disponible ...