Cuando sh es un enlace simbólico a bash o dash, bash se limita al cumplimiento POSIX, por lo que debería ser 100% compatible con sh?

8

De la diferencia entre bash y sh :

Regrese a la pregunta: si tiene /bin/shun enlace a bash, entonces bash no se comportará de la misma manera cuando se lo llama que /bin/shcuando se lo llama /bin/bash. Cuando se llama como sh, se limitará principalmente a la conformidad POSIX más un conjunto limitado de extensiones.

¿Significa que cada vez que me encuentro con un script de shell en Linux con un shebang para sh: #!/bin/shincluso si en esa distribución, bin/shes un enlace simbólico a otro shell, como dash o bash, debería ser 100% compatible con el shell bourne, ya que se limita a un conjunto limitado de extensiones? ¿Entonces podría ejecutarlos en FreeBSD? ¿Hay alguna excepción a eso? ¿O debería estar seguro de asumir que funcionará?

Entonces, si está en una distribución, ¿ bin/shhay un enlace simbólico a bin/bash, y el uso de un script #!/bin/shy el script contienen bashism, no se ejecutará, ya que bash querrá estar en modo sh?

usuario1115057
fuente

Respuestas:

16

No, si /bin/shes un enlace simbólico a golpe, golpe entra en modo de solo POSIX - a partir de bash :

Cuando se invoca como sh, bash ingresa al modo posix después de leer los archivos de inicio.

Si ahora busca el modo posix en la página de manual de bash , verá que algunos shell incorporados tienen gusto timeo se sourcecomportan de manera diferente. Eso es todo. bashishms como escribir functionantes de declarar una función o usar en sourcelugar de .seguir funcionando, pero los comandos pueden comportarse de manera diferente.

Entonces, si /bin/shes un enlace simbólico a /bin/bashtodos los bashishms típicos, todavía funciona.

Para obtener una lista bastante extensa de las diferencias en el modo Posix, consulte el manual de referencia de bash .

Ulrich Dangel
fuente
Así que supongo que lo mejor es probar todas las secuencias de comandos en la herramienta checkbashism. Escuché que algunas distribuciones, como Debian y Ubuntu (necesitan confirmación para esta), tenían su enlace simbólico bin / sh ahora en el tablero. ¿El tablero es compatible con la carcasa de bourn? En caso afirmativo, al menos todos los scripts de shell Debian y Ubuntu deberían estar bien en FreeBSD.
user1115057
@ user1115057 solo scripts de shell con /bin/shcomo shebang. Un script de shell todavía puede usar explícitamente /bin/bash. De todos modos, la mayoría de los scripts de shell probablemente se ejecutarán bien en / bin / sh, pero el problema serán las herramientas del usuario, por ejemplo, la mayoría de los scripts de shell esperan el usuario GNU, lo que probablemente será más un problema que un error de sintaxis. También agregué un enlace a la referencia de bash que enumera los diferentes comportamientos en modo posix
Ulrich Dangel,
De acuerdo con lo que leí, BSD usa ash como su bin / sh, mientras que Debian y Ubuntu usan dash. Si esos shell son compatibles, significa que ya no tendré problemas con shebang #! / Bin / sh. Pero como dijiste, habrá otro problema relacionado con el país de usuario ...
user1115057
@ user1115057 dash tampoco es perfecto, p. ej. wiki.ubuntu.com/DashAsBinSh/#echo de todos modos, la mayoría de los scripts de shell son bastante simples y se pueden portar con bastante facilidad ... buena suerte
Ulrich Dangel
Pero el tablero y la ceniza son compatibles ¿verdad?
user1115057
8

Parece haber cierta confusión en torno al caparazón de Bourne. El shell Bourne era un shell de Unix hace décadas, en los días previos a POSIX. Hoy en día "sh" es una implementación u otra de un shell que implementa la especificación POSIX, entre las cuales tenemos bash, pdksh, AT&T ksh, nuevos shells Almquist y sus derivados que se han hecho compatibles con POSIX (incluido el "sh" de algunos BSD) , otros BSDs se basan en pdksh y Debian ash (dash)). Incluso zsh tiene un modo en el que es principalmente compatible con POSIX.

El shell Bourne no es compatible con POSIX, y no se puede encontrar en muchos sistemas hoy en día. Donde se encuentra el shell Bourne o donde no lo es, siempre habrá una "sh" que sea compatible con POSIX (y no será el shell Bourne), generalmente /binmientras que una excepción notable (molesta) es Solaris.

Tenga en cuenta que antes del shell Bourne, y estamos hablando hace más de 30 años, "sh" era el shell Thompson. Ya no estamos escribiendo guiones compatibles con el shell Thompson. Del mismo modo, deberíamos dejar de pensar en "sh" como el shell Bourne.

Ahora "sh" es una especificación, no muchas variantes a veces incompatibles de una implementación. Eso hace que sea mucho más fácil escribir scripts portátiles. Solo sigue las especificaciones .

Eso va para "sh" y todas las utilidades estándar (sed, cut, tr ...)

Stéphane Chazelas
fuente
+1 para "escribir en la especificación". Pero lamentablemente, eso a menudo no es suficiente para la portabilidad. Por ejemplo, ¿qué pasa si uno quiere usar patrones de estilo egrep en sed? La especificación no proporciona esto. En los sistemas con utilidades basadas en Gnu (o BusyBox), usted usa sed -r. En sistemas con utilidades basadas en BSD, usted usa sed -E. El sed de FreeBSD acepta ambos, pero el Mac OS X solo acepta -E. Y así sucesivamente y así sucesivamente.
dubiousjim
Eso no viene al caso. La especificación no lo proporciona, por lo que no puede usarlo de manera portátil / POSIX. Si usa BRE, eso funcionará en todos los sistemas conformes POSIX, esa es una garantía dada por POSIX, por eso es útil. Fuera de POSIX como usted dice, no hay esperanza ya que los seds no admiten ERE o lo admiten con una opción diferente o una sintaxis de ERE diferente. Tenga en cuenta que los ERE son menos capaces que los BRE (solo la sintaxis se extiende en los ERE para ahorrarle algo de escritura. Los ERE se pueden traducir a BRE, lo contrario no es cierto (los BRE \(...\)\1no tienen traducción en los ERE estándar).
Stéphane Chazelas
1
Me doy cuenta de que los ERE (POSIX) carecen de referencias posteriores; De hecho, he participado en la edición de esa parte del estándar. No es correcto que los ERE POSIX sean estrictamente menos capaces que los BRE, ya que en el estándar actual, la alternancia no está definida para los BRE. Sin embargo, no conozco ningún motor \|de expresiones regulares que no honre a los BRE. Estoy dispuesto a escribir de la manera más portátil posible. Solo estaba haciendo la observación (me pareció muy apreciada) de que esto puede ser doloroso, y algunas veces escribir a POSIX simplemente no es posible. En algún lugar tienen enlaces que exhiben muchas de esas perversiones; los buscará
dubiousjim
Buen punto sobre la alternancia, lo olvidé y me corrijo. Con sed, es poco probable que esté bloqueando, ya que puede usar varias expresiones para que coincidan con las expresiones regulares alternativas. Hay un awk en el cofre de herramientas estándar que se puede usar si se necesitan ERE. Muy rara vez me encuentro con el cofre de herramientas estándar, y cuando lo hago, generalmente son casos en los que otro idioma como perl es más apropiado, pero veo su punto (aunque todavía creo que no está al lado en este hilo sobre escribir scripts portátiles)
Stéphane Chazelas
Un ejemplo que pensé de improviso: las líneas shebang (en la parte superior de cada script de shell) no se especifican en POSIX. Además, no estoy seguro de haber usado un sistema que sea 100% compatible con POSIX. Por ejemplo, POSIX dice que puede incluir nuevas líneas dentro, ${VAR:=stuff...here}pero muchos shells no lo permiten, debe poner comillas stuff...here.
dubiousjim