¿Qué significa ser "compatible con sh"?


63

He visto la frase "sh compatible" utilizada generalmente en referencia a las conchas. No estoy seguro de si también se aplica a los programas que podrían ejecutarse desde shells.

¿Qué significa que un shell u otro programa sea "compatible con sh"? ¿Qué significaría ser "sh incompatible"?

Editar: esta pregunta sobre la diferencia entre bash y sh es muy relevante: diferencia entre sh y bash

Todavía me gustaría una respuesta directa a lo que significa ser "compatible con sh". Una expectativa razonable podría ser que "sh compatible" significa "implementa el lenguaje de comandos de Shell", pero ¿por qué hay tantos shells "compatibles con sh" y por qué son diferentes?


1
Para un script de shell, se refiere a si ese script usa o no la sintaxis compatible (ejecutable) con Bourne Shell ( sh). Para un shell diferente, se refiere a si ese shell puede ejecutar scripts de shell Bourne.
HalosGhost

Si quieres aprender inventor de conchas, puedes visitar mi respuesta en unix.stackexchange.com/questions/45684/…
PersianGulf

Respuestas:


116

¿Por qué hay tantos proyectiles "compatibles con sh"?

El shell Bourne se lanzó por primera vez públicamente en 1979 como parte de Unix V7 . Dado que casi todos los sistemas Unix y similares a Unix descienden de V7 Unix , aunque solo sea espiritualmente, el shell Bourne ha estado con nosotros "para siempre".

El caparazón Bourne en realidad reemplazó un caparazón anterior, retomó el caparazón Thompson , pero sucedió tan temprano en la historia de Unix que hoy está casi olvidado. El shell Bourne es un superconjunto del shell Thompson

Se llamaron los proyectiles Bourne y Thompson sh. El shell especificado por POSIX también se llama sh. Entonces, cuando alguien dice " shcompatible", se está refiriendo a esta serie de proyectiles. Si quisieran ser específicos, dirían "shell POSIX" o "shell Bourne". ³

El shell POSIX se basa en la versión de 1988 de KornShell , que a su vez estaba destinado a sustituir el Bourne Shell en AT & T Unix, leapfrogging el shell C BSD en términos de features.⁴ En la medida en que kshes el antepasado de la shell POSIX, la mayoría Los sistemas Unix y similares a Unix incluyen alguna variante del shell Korn hoy. Las excepciones son generalmente pequeños sistemas integrados, que no pueden permitirse el espacio que ocupa un shell POSIX completo.

Dicho esto, el shell Korn, como algo distinto del shell POSIX, nunca se hizo realmente popular fuera del mundo comercial de Unix. Esto se debe a que su ascenso correspondió con los primeros años de comercialización de Unix, por lo que quedó atrapado en las guerras de Unix . BSD Unixes lo evitó a favor del shell C, y su código fuente no estaba disponible para su uso gratuito en Linux cuando comenzó. Por lo general, eligen GNU Bash , uno de esos sh-compatibles de los que estás hablando.

Esa asociación temprana entre Linux y Bash prácticamente selló el destino de muchos otros shells, incluidos ksh, cshy tcsh. Hoy en día, todavía hay personas que usan esos proyectiles, pero son muy minoritarios.

Toda esta historia explica por qué a los creadores de los recién llegados relativamente les gusta bash, zshy yashdecidieron hacerlos shcompatibles: la compatibilidad Bourne / POSIX es lo mínimo que debe proporcionar un shell para sistemas similares a Unix para obtener una adopción generalizada.

En muchos sistemas, el shell de comandos interactivo predeterminado y /bin/shson cosas diferentes. /bin/shtal vez:

  • La cáscara Bourne original. Esto es común en sistemas UNIX® más antiguos, como Solaris 10 (lanzado en 2005) y sus predecesores.

  • Una carcasa con certificación POSIX. Esto es común en los sistemas UNIX® más nuevos, como Solaris 11 (2010).

  • El caparazón de Almquist . Este es un clon de shell Bourne / POSIX de código abierto lanzado originalmente en Usenet en 1989 , que luego se contribuyó al CSRG de Berkeley para su inclusión en la primera versión BSD que no contiene código fuente de AT&T, 4.4BSD-Lite . El shell Almquist a menudo se llama ash, incluso cuando se instala como /bin/sh.

    4.4BSD-Lite, a su vez, se convirtió en la base de todos los derivados de BSD modernos, /bin/shpermaneciendo como un derivado de Almquist en la mayoría de ellos, con una excepción importante que se detalla a continuación. Puede ver esta descendencia directa en los repositorios de código fuente para NetBSD y FreeBSD : enviaban un derivado de shell Almquist desde el día 1.

    Hay dos ashtenedores importantes fuera del mundo BSD:

    1. dash, adoptada por Debian y Ubuntu en 2006 como la /bin/shimplementación predeterminada . (Bash sigue siendo el shell de comando interactivo predeterminado en los derivados de Debian).

    2. El ashcomando en BusyBox , que se usa con frecuencia en Linux embebidos y se puede usar para implementar /bin/sh. Ya que es posterior dashy que se deriva de edad de Debian ashpaquete , he elegido para considerarlo un derivado del dashlugar de ash, a pesar de su nombre de la orden dentro de BusyBox.

      (BusyBox también incluye una alternativa menos funcional a la ashllamada hush. Por lo general, solo uno de los dos se integrará en cualquier binario de BusyBox: ashde forma predeterminada, pero hushcuando el espacio es realmente limitado. Por lo tanto, /bin/shen los sistemas basados ​​en BusyBox no siempre es dashsimilar).

  • GNU Bash , que deshabilita la mayoría de sus extensiones que no son POSIX cuando se llama comosh .

    Esta opción es típica en las variantes de escritorio y servidor de Linux, a excepción de Debian y sus derivados. Mac OS X también lo ha hecho desde Panther, lanzado en 2003.

  • Un shell con ksh93extensiones POSIX , como en OpenBSD . Aunque el shell de OpenBSD cambia el comportamiento para evitar la sintaxis y las incompatibilidades semánticas con los shells Bourne y POSIX cuando se lo llama sh, no deshabilita ninguna de sus extensiones puras, ya que no entran en conflicto con los shells más antiguos.

    Esto no es común; no deberías esperar ksh93características en /bin/sh.

Usé "script de shell" arriba como un término genérico que significa scripts de shell Bourne / POSIX. Esto se debe a la ubicuidad de las conchas de la familia Bourne. Para hablar sobre secuencias de comandos en otros shells, debe dar un calificador, como "Script de shell C". Incluso en sistemas donde un shell de la familia C es el shell interactivo predeterminado, es mejor usar el shell Bourne para las secuencias de comandos.

Es revelador que cuando Wikipedia clasifica los shells de Unix , los agrupan en Bourne shell compatible, C shell compatible y "otro".

Este diagrama puede ayudar:

Los shells de Unix: Bourne, Korn, POSIX, C y rc Shell Families

(Haga clic para ver la versión SVG, 31 kB, o ver la versión PNG a tamaño completo , 218 kB).

¿Qué significaría ser "sh incompatible"?

Alguien que habla de shalgo incompatible generalmente significa una de tres cosas:

  1. Se refieren a uno de esos "otros" proyectiles.

  2. Están haciendo una distinción entre las familias de shell Bourne y C.

  3. Están hablando de alguna característica específica en un shell de la familia Bourne que no está en todos los otros shells de la familia Bourne. ksh93, bashy zshen particular tienen muchas características que no existen en los shells "estándar" anteriores. Esos tres también son mutuamente incompatibles de muchas maneras, una vez que superas el POSIX / ksh88base compartido .

Es un error clásico escribir un script de shell con una #!/bin/sh línea shebang en la parte superior pero usar extensiones de shell Bash o Korn dentro. Dado que /bin/shes uno de los shells en el diagrama de la familia Korn / POSIX anterior en tantos sistemas en estos días, tales scripts funcionarán en el sistema en el que están escritos, pero luego fallarán en los sistemas donde /bin/shhay algo de la familia de shells Bourne más amplia. La mejor práctica es utilizar #!/bin/basho #!/bin/kshShebang líneas si la secuencia de comandos utiliza este tipo de extensiones.

Hay muchas maneras de verificar si un script de shell de la familia Bourne es portátil:

  • Ejecútelo checkbashisms, una herramienta del proyecto Debian que comprueba un script para " bashisms ".

  • Ejecútelo en poshun shell en el repositorio de paquetes de Debian que implementa intencionalmente solo las características especificadas por SUS3 , además de algunas otras características menores .

  • Ejecútelo oshdesde el proyecto Schily Tools , una versión mejorada del shell Bourne como fuente abierta de Sun como parte de OpenSolaris en 2005, lo que lo convierte en una de las formas más fáciles de obtener un shell Bourne de estilo 1979 en una computadora moderna.

    La distribución de Schily Tools también incluye boshun shell de tipo POSIX con muchas características no estándar , pero que puede ser útil para probar la compatibilidad de los scripts de shell destinados a ejecutarse en todos los shells de la familia POSIX. Tiende a ser más conservador en su conjunto de características que bash, zshy las versiones mejoradas de ksh93.

    Schily Tools también incluye un shell llamado bsh, pero esa es una rareza histórica que no es en absoluto un shell de la familia Bourne.

  • Vaya al capítulo de Programación de Shell portátil en el manual de GNU Autoconf . Puede reconocer algunas de las construcciones problemáticas de las que habla en sus scripts.

¿Por qué son diferentes?

Por las mismas razones, todo "¡Nuevo y mejorado!" las cosas son diferentes:

  • La versión mejorada solo podría mejorarse rompiendo la compatibilidad con versiones anteriores.

  • Alguien pensó en una forma diferente para que algo funcione, que les gusta más, pero que no es la misma forma en que funcionaba la anterior.

  • Alguien intentó reimplementar un viejo estándar sin entenderlo completamente, por lo que se equivocaron y crearon una diferencia involuntaria.


Notas al pie y a un lado :

  1. Las primeras versiones de BSD Unix eran solo colecciones de software adicionales para V6 Unix. Dado que el shell Bourne no se agregó a AT&T Unix hasta V7, BSD técnicamente no comenzó a tener el shell Bourne. La respuesta de BSD a la naturaleza primitiva del shell Thompson era el shell C .

    Sin embargo, las primeras versiones independientes de BSD (2.9BSD y 3BSD) se basaron en V7 o su sucesor portátil UNIX / 32V , por lo que incluyeron el shell Bourne.

    (La línea 2BSD se convirtió en una bifurcación paralela de BSD para las minicomputadoras PDP de Digital , mientras que las líneas 3BSD y 4BSD aprovecharon los tipos de computadora más nuevos como las estaciones de trabajo Vaxen y Unix . 2.9BSD era esencialmente la versión PDP de 4.1cBSD; eran y código compartido contemporánea . PDP no desaparecen cuando el VAX llegó, por lo que la línea de 2BSD se sigue arrastrando los pies a lo largo ).

    Es seguro decir que el shell Bourne estaba en todas partes del mundo Unix en 1983. Esa es una buena aproximación a "para siempre" en la industria informática. MS-DOS obtuvo un sistema de archivos jerárquico ese año (¡awww, qué lindo!) Y el primer Macintosh de 24 bits con su pantalla de 9 "en blanco y negro , no en escala de grises, literalmente en blanco y negro , no saldría hasta principios del próximo año.

  2. El caparazón de Thompson era bastante primitivo para los estándares actuales. Era solo un shell de comandos interactivo, en lugar del entorno de programación de script que esperamos hoy. Tenía cosas como tuberías y redirección de E / S, que consideramos como parte prototípica de un "shell de Unix", por lo que pensamos en el shell de comandos de MS-DOS como obteniéndolos de Unix.

    El shell Bourne también reemplazó al shell PWB , que agregó cosas importantes al shell Thompson como la capacidad de programación ( if, switchy while) y una forma temprana de variables de entorno. El shell PWB es aún menos recordado que el shell Thompson, ya que no formaba parte de todas las versiones de Unix.

  3. Cuando alguien no es específico acerca de la compatibilidad de shell POSIX vs Bourne, hay una gran variedad de cosas que podrían significar.

    En un extremo, podrían estar usando el shell Bourne de 1979 como línea de base. Una " shsecuencia de comandos compatible" en este sentido significaría que se espera que funcione perfectamente en el verdadero shell Bourne o cualquiera de sus sucesores y clones: ash, bash, ksh, zsh, etc.

    Alguien en el otro extremo asume el shell especificado por POSIX como una línea de base. Tomamos tantas características de shell POSIX como "estándar" en estos días que a menudo olvidamos que en realidad no estaban presentes en el shell Bourne: aritmética incorporada, control de trabajos, historial de comandos, alias, edición de línea de comandos, la $()forma de comando sustitución, etc.

  4. Aunque el shell Korn tiene raíces que se remontan a principios de la década de 1980, AT&T no lo envió en Unix hasta System V Release 4 en 1988. Dado que muchos Unix comerciales se basan en SVR4, esto incluyó kshcasi todos los Unix comerciales relevantes de finales de 1980 en adelante.

    (Algunos sabores extraños de Unix basados ​​en SVR3 y anteriores se mantuvieron en piezas del mercado después del lanzamiento de SVR4, pero fueron los primeros contra la pared cuando llegó la revolución ).

    1988 es también el año en que salió el primer estándar POSIX , con su "shell POSIX" basado en Korn shell. Más tarde, en 1993, salió una versión mejorada del shell Korn. Desde POSIX efectivamente clavado el original en su lugar, kshbifurcado en dos versiones principales: ksh88y ksh93, nombrado después de los años involucrados en su división.

    ksh88no es totalmente compatible con POSIX, aunque las diferencias son pequeñas, por lo que algunas versiones del ksh88shell se parchearon para ser compatibles con POSIX. (Esto es de una entrevista interesante en Slashdot con el Dr. David G. Korn . Sí, el tipo que escribió la concha).

    ksh93es un superconjunto totalmente compatible del shell POSIX . El desarrollo en ksh93ha sido esporádico desde que el repositorio de la fuente primaria se mudó de AT&T a GitHub con el lanzamiento más reciente de aproximadamente 3 años cuando escribo esto, ksh93v. (El nombre base del proyecto permanece ksh93con sufijos agregados para denotar versiones de lanzamiento más allá de 1993).

    Los sistemas que incluyen un shell Korn como algo separado del shell POSIX generalmente lo hacen disponible /bin/ksh, aunque a veces se esconde en otro lugar.

    Cuando hablamos sobre kshel shell Korn por su nombre, estamos hablando de ksh93características que lo distinguen de sus subconjuntos de shell Bourne y POSIX compatibles con versiones anteriores. Raramente te encuentras con lo puro ksh88hoy.

  5. AT&T mantuvo el código fuente del shell Korn propietario hasta marzo de 2000 . En ese momento, la asociación de Linux con GNU Bash era muy fuerte. Bash y ksh93 cada uno tienen ventajas sobre el otro , pero en este punto la inercia mantiene a Linux estrechamente asociado con Bash.

    En cuanto a por qué los primeros proveedores de Linux eligen más comúnmente GNU Bash pdksh, que estaba disponible en el momento en que Linux comenzaba, supongo que es porque gran parte del resto de la tierra de usuarios también provino del proyecto GNU . Bash también es algo más avanzado que pdksh, ya que los desarrolladores de Bash no se limitan a copiar las características del shell Korn.

    El trabajo se pdkshdetuvo aproximadamente cuando AT&T lanzó el código fuente al verdadero shell Korn. Hay dos horquillas principales que se siguen manteniendo, sin embargo: la OpenBSD pdkshy el Korn Shell MirBSD,mksh .

    Me parece interesante que mkshsea ​​la única implementación de shell Korn actualmente empaquetada para Cygwin.

  6. GNU Bash va más allá de POSIX de muchas maneras, pero puede pedirle que se ejecute en un modo POSIX más puro .

  7. csh/ tcshsolía ser el shell interactivo predeterminado en BSD Unixes a principios de los 90

    Siendo una variante BSD , las primeras versiones de Mac OS X fueron así, a través de Mac OS X 10.2 "Jaguar" . OS X cambió el shell predeterminado de tcshBash en OS X 10.3 "Panther" . Este cambio no afectó a los sistemas actualizados desde 10.2 o anteriores. Los usuarios existentes en esos sistemas convertidos mantuvieron su tcshshell.

    FreeBSD afirma que todavía se usa tcshcomo shell predeterminado , pero en el FreeBSD 10 VM que tengo aquí, el shell predeterminado parece ser una de las variantes de shell Almquist compatibles con POSIX . Esto también es cierto en NetBSD.

    OpenBSD usa una bifurcación pdkshcomo shell predeterminado en su lugar.

    La mayor popularidad de Linux y OS X hace que algunas personas deseen que FreeBSD también cambie a Bash, pero no lo harán pronto por razones filosóficas . Es fácil cambiarlo , si esto te molesta.

  8. Es raro encontrar un sistema con un shell Bourne verdaderamente vainilla como en /bin/shestos días. Tienes que salir de tu camino para encontrar algo lo suficientemente cerca para pruebas de compatibilidad.

    Solo conozco una forma de ejecutar un auténtico Bourne shell de 1979 en una computadora moderna: use las imágenes de disco de Ancient Unix V7 con el simulador SIMH PDP-11 del Proyecto de simulación de historia de computadora . SIMH se ejecuta en casi todas las computadoras modernas , no solo en las Unix. SIMH incluso se ejecuta en Android y en iOS .

    Con OpenSolaris , Sun abrió por primera vez la versión SVR4 del shell Bourne. Antes de eso, el código fuente para las versiones posteriores a V7 del shell Bourne solo estaba disponible para aquellos con una licencia de código fuente Unix.

    Ese código ahora está disponible por separado del resto del difunto proyecto OpenSolaris de un par de fuentes diferentes.

    La fuente más directa es el proyecto de shell Heirloom Bourne . Esto estuvo disponible poco después del lanzamiento original de 2005 de OpenSolaris. Algunos trabajos de portabilidad y corrección de errores se realizaron en los próximos meses, pero luego el desarrollo del proyecto se detuvo.

    Jörg Schilling ha hecho un mejor trabajo al mantener una versión de este código como oshen su paquete Schily Tools . Ver arriba para más información sobre esto.

    Tenga en cuenta que estos shells derivados de la versión del código fuente de 2005 contienen compatibilidad con conjuntos de caracteres de varios bytes , control de trabajos, funciones de shell y otras características que no están presentes en el shell Bourne original de 1979.

    Una forma de saber si está en un shell Bourne original es ver si admite una función no documentada agregada para facilitar la transición desde el shell Thompson: ^como un alias para |. Es decir, un comando como ls ^ moredará un error en un shell de tipo Korn o POSIX, pero se comportará como ls | moreen un shell Bourne verdadero.

  9. De vez en cuando te encuentras con un fish, scsho rc/esadherente, pero son aún más raros que los fanáticos de C.

    La rcfamilia de los shells no se usa comúnmente en los sistemas Unix / Linux, pero la familia es históricamente importante, y así es como se ganó un lugar en el diagrama anterior. rces la cáscara estándar del Plan 9 del sistema operativo Bell Labs , una especie de sucesor de la décima edición de Unix , creada como parte de la investigación continua de Bell Labs en el diseño del sistema operativo. Es incompatible con Bourne y C shell a nivel de programación; Probablemente hay una lección allí.

    La variante más activa de rcparece ser la mantenida por Toby Goodwin , que se basa en el rcclon Unix de Byron Rakitzis.


Si desea conocer más relaciones, por ejemplo, con UNOS "command", "bsh" y el reciente Bourne Shell, envíeme una nota. Como pista: el comando UNOS tenía un comando incorporado "do" que actuaba como un script de shell de una línea con argumentos. Esta idea se transfirió al Bourne Shell como "dosh" y permite alias parametrizables, algo que no se puede obtener de ksh o bash.
schily

Vale la pena señalar que pdksh se basa en el shell Forsyth. Hoy en día se ha olvidado principalmente, pero tiene cierta importancia histórica en el patrimonio pdksh, pero también porque era el caparazón de algunas versiones de minix y había sido portado a msdos.
Stéphane Chazelas

25

"sh compatible" se refiere a POSIXsh , el shell básico que se requiere para existir en todos los sistemas compatibles. Un script compatible con sh debería funcionar en cualquier máquina compatible con POSIX.

La razón por la que es necesario decirlo es que comúnmente /bin/shes un enlace simbólico /bin/bash, lo que ha permitido que algunos se deslizan en bash scripts que se declaran a utilizar shcon #!/bin/sh. Estos scripts no funcionan en sistemas que no se usan bashcomo /bin/sh, incluidos algunos Unices comerciales para siempre, y Debian y derivados recientemente.

En particular, ha habido una tendencia a usar dash, Debian Almquish Shell, como el valor predeterminado shúltimamente, porque es más pequeño y está destinado a ser más rápido. Esa tendencia ha resaltado muchos de esos Bashismos que se encontraban en supuestos shguiones. Describir algo como "compatible con sh" indica que está diseñado explícitamente para trabajar con estos sistemas al permanecer completamente dentro del lenguaje especificado por POSIX : todos los shells implementarán un superconjunto de esa funcionalidad, por lo que está garantizado que funcione en todas partes, pero sus extensiones no son compatible el uno con el otro.

Diferentes shells tienen sus propios historiales de desarrollo y divergieron en diferentes direcciones a lo largo del tiempo, ya que agregaron funciones para ayudar al uso interactivo de sus usuarios, o extensiones de secuencias de comandos como matrices asociativas. Un script "incompatible con sh" usaría algunas de estas características de extensión no estándar, como los [[condicionales de Bash .

Las características que no son POSIX en bashy tcshy en zshtodos los otros shells actuales son útiles , y hay muchas ocasiones en las que puede quererlas o necesitarlas. Simplemente no deberían usarse en un script que se declare a sí mismo para trabajar /bin/sh, porque no puede confiar en que esas características estén en la shimplementación base en el sistema en el que se está ejecutando.

Un script que necesita usar, por ejemplo, matrices asociativas, debería garantizar que se ejecute en bashlugar de sh:

#!/bin/bash
declare -A array

Eso funcionará en cualquier lugar con bash. Los scripts que no necesitan la funcionalidad extendida y están destinados a ser portátiles deberían declarar que usan shy se adhieren al lenguaje de comandos de la base shell.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.