GNU/Linux >> Tutoriales Linux >  >> Linux

¿Qué significa ser "sh compatible"?

He visto que la frase "compatible con sh" se usa generalmente en referencia a los proyectiles. No estoy seguro de si también se aplica a los programas que pueden 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 "compatible con sh" significa "implementa el lenguaje de comandos de Shell", pero entonces, ¿por qué hay tantos shells "compatibles con sh" y por qué son diferentes?

Respuesta aceptada:

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

El shell Bourne se lanzó públicamente por primera vez 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 shell Bourne en realidad reemplazó a un shell anterior, rebautizado como shell Thompson, pero sucedió tan temprano en la historia de Unix que hoy en día está casi olvidado. El caparazón Bourne es un superconjunto del caparazón Thompson.²

Tanto los proyectiles de Bourne como los de Thompson se llamaban sh . El shell especificado por POSIX también se llama sh . Entonces, cuando alguien dice sh -compatibles, se refieren a mano 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 reemplazar el shell Bourne en AT&T Unix, superando al shell BSD C en términos de funciones.⁴ En la medida en que ksh es el antepasado del shell POSIX, la mayoría de los sistemas Unix y similares a Unix incluyen alguna variante del shell Korn en la actualidad. 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 llegó a ser realmente popular fuera del mundo comercial de Unix. Esto se debe a que su ascenso se correspondió con los primeros años de la 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 gratuitamente para su uso en Linux cuando comenzó.⁵ Entonces, cuando los primeros distribuidores de Linux buscaron un shell de comando para su kernel de Linux, normalmente elegían 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, incluido ksh , csh y tcsh . Todavía hay fanáticos que usan esos proyectiles hoy en día, pero son una minoría.⁷

Toda esta historia explica por qué los creadores de los recién llegados como bash , zsh y yash eligió hacerlos sh -compatible: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/sh son cosas diferentes. /bin/sh puede ser:

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

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

  • La concha 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 de BSD que no contiene código fuente de AT&T, 4.4BSD-Lite. El shell de Almquist a menudo se llama ash , incluso cuando se instala como /bin/sh .

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

    Hay dos ash importantes bifurcaciones fuera del mundo BSD:

    1. dash , adoptado por Debian y Ubuntu en 2006 como /bin/sh predeterminado implementación. (Bash sigue siendo el interactivo predeterminado shell de comandos en derivados de Debian.)

    2. La ash comando en BusyBox, que se usa con frecuencia en Linux incorporados y puede usarse para implementar /bin/sh . Dado que es posterior a dash y se derivó del antiguo ash de Debian paquete, he optado por considerarlo un derivado de dash en lugar de ash , a pesar de su nombre de comando dentro de BusyBox.

      (BusyBox también incluye una alternativa menos funcional a ash llamado hush . Por lo general, solo uno de los dos se integrará en cualquier binario BusyBox dado:ash por defecto, pero hush cuando el espacio es realmente estrecho. Por lo tanto, /bin/sh en los sistemas basados ​​en BusyBox no siempre es dash -me gusta.)

  • Fiesta GNU , que deshabilita la mayoría de sus extensiones que no son POSIX cuando se llama como sh .

    Esta elecció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 ha hecho esto desde Panther, lanzado en 2003.

  • Un caparazón con ksh93 Extensiones POSIX , como en OpenBSD. Aunque el shell de OpenBSD cambia de comportamiento para evitar incompatibilidades sintácticas y semánticas con los shells Bourne y POSIX cuando se llama como sh , no deshabilita ninguna de sus extensiones puras, siendo aquellas que no entran en conflicto con shells anteriores.

    Esto no es común; no debe esperar ksh93 funciones en /bin/sh .

Usé "script de shell" arriba como un término genérico que significa secuencias de comandos 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 proporcionar un calificador, como "script de shell C". Incluso en los sistemas en los que un shell de la familia C es el shell interactivo predeterminado, es mejor utilizar el shell Bourne para las secuencias de comandos.

Es revelador que cuando Wikipedia clasifica los shells de Unix, los agrupa en compatibles con shell Bourne, compatibles con shell C y "otros".

Relacionado:¿Comando fácil de usar para enumerar todos los usuarios en el sistema Ubuntu?

Este diagrama puede ayudar:

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

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

Alguien hablando de un sh -cosa incompatible típicamente significa una de tres cosas:

  1. Se refieren a uno de esos "otros" caparazones.⁹

  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 caparazón de la familia Bourne que no está en todos los demás caparazones de la familia Bourne. ksh93 , bash y zsh en particular, tienen muchas características que no existen en los shells "estándar" más antiguos. Esos tres también son incompatibles entre sí de muchas maneras, una vez que superas el POSIX/ksh88 compartido base.

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

Hay muchas formas de comprobar si un script de shell de la familia Bourne es portátil:

  • Ejecute checkbashisms en él, una herramienta del proyecto Debian que verifica un script en busca de "bashisms".

  • Ejecútelo bajo posh , un shell en el repositorio de paquetes de Debian que implementa deliberadamente solo funciones especificadas por SUS3, además de algunas otras funciones menores.

  • Ejecútelo bajo obosh del proyecto Schily Tools, una versión mejorada del shell Bourne de código abierto 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 al estilo de 1979 en una computadora moderna.

    La distribución de Schily Tools también incluye bosh , un shell de tipo POSIX con muchas funciones 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 , zsh y las versiones mejoradas de ksh93 .

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

  • Lea el capítulo Programación de Portable Shell en el manual GNU Autoconf. Es posible que reconozca algunas de las construcciones problemáticas de las que habla en sus guiones.

¿Por qué son diferentes?

Por las mismas razones, todos los programas "¡Nuevos y mejorados!" las cosas son diferentes:

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

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

  • Alguien intentó volver a implementar un estándar anterior sin comprenderlo por completo, por lo que se equivocó y creó una diferencia no intencional.

Notas al pie y apartes :

  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ó con el shell Bourne. La respuesta de BSD a la naturaleza primitiva del shell Thompson fue el shell C.

    Sin embargo, las primeras versiones independientes de BSD (2.9BSD y 3BSD) se basaron en V7 o en su sucesor portátil UNIX/32V, por lo que lo hicieron incluir el shell de 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 computadoras más nuevos como las estaciones de trabajo Vaxen y Unix. 2.9BSD era esencialmente la versión PDP de 4.1cBSD; eran contemporáneo y código compartido. Los PDP no desaparecieron cuando llegó el VAX, por lo que la línea 2BSD todavía se tambalea.)

    Es seguro decir que el shell Bourne estaba en todas partes en el mundo de 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 negro y blanco — no saldría hasta principios del próximo año.

  2. El caparazón Thompson era bastante primitivo para los estándares actuales. Era solo un shell de comando interactivo, en lugar del entorno de programación de scripts que esperamos hoy. Tenía cosas como conductos y redirección de E/S, que consideramos prototípicamente parte de un "shell de Unix", por lo que pensamos que el shell de comandos de MS-DOS los obtiene 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 , switch y while ) y una forma temprana de variables de entorno. El shell PWB es incluso menos recordado que el shell Thompson, ya que no formaba parte de todas las versiones de Unix.

  3. Cuando alguien no es específico sobre la compatibilidad de POSIX vs Bourne shell, 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. Un “sh -secuencia de comandos compatible” en este sentido significaría que se espera que se ejecute perfectamente en el verdadero shell de 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 línea de base. Tomamos tantas funciones 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 integrada, control de trabajos, historial de comandos, alias, edición de línea de comandos, $() forma de sustitución de mando, etc.

  4. Aunque el shell de 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 puso ksh en prácticamente todos los Unix comerciales relevantes desde finales de la década de 1980 en adelante.

    (Algunos sabores extraños de Unix basados ​​en SVR3 y anteriores mantuvieron partes del mercado más allá 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 "carcasa POSIX" basada en shell Korn. Más tarde, en 1993, salió una versión mejorada de la coraza Korn. Dado que POSIX clavó efectivamente el original en su lugar, ksh bifurcado en dos versiones principales:ksh88 y ksh93 , llamado así por los años involucrados en su separación.

    ksh88 no es completamente compatible con POSIX, aunque las diferencias son pequeñas, por lo que algunas versiones del ksh88 shell fueron parcheados para ser compatibles con POSIX. (Esto de una interesante entrevista en Slashdot con el Dr. David G. Korn. Sí, el tipo que escribió el caparazón).

    ksh93 es un superconjunto totalmente compatible del shell POSIX. Desarrollo en ksh93 ha sido esporádico desde que el repositorio de origen principal se mudó de AT&T a GitHub y la versión más reciente tiene aproximadamente 3 años mientras escribo esto, ksh93v. (El nombre base del proyecto sigue siendo ksh93 con sufijos agregados para indicar versiones posteriores a 1993).

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

    Cuando hablamos de ksh o el shell Korn por su nombre, estamos hablando de ksh93 características que lo distinguen de sus subconjuntos de shell Bourne y POSIX compatibles con versiones anteriores. Rara vez te encuentras con el ksh88 puro hoy.

  5. AT&T mantuvo la propiedad del código fuente de la shell Korn hasta marzo de 2000. En ese momento, la asociación de Linux con GNU Bash era muy sólida. Bash y ksh93 cada uno tiene 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 sobre pdksh , que era disponible en el momento en que comenzó Linux, supongo que se debe a que gran parte del resto de la tierra de los 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 funciones de shell de Korn.

    Trabajar en pdksh se detuvo cuando AT&T lanzó el código fuente al verdadero shell de Korn. Sin embargo, hay dos bifurcaciones principales que aún se mantienen:OpenBSD pdksh y MirBSD Korn Shell, mksh .

    Me parece interesante que mksh es la única implementación de shell de Korn empaquetada actualmente 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 /tcsh solía ser el shell interactivo predeterminado en BSD Unixes a principios de la década de 1990.

    Al ser una variante de BSD, las primeras versiones de Mac OS X eran así, pasando por Mac OS X 10.2 “Jaguar”. OS X cambió el shell predeterminado de tcsh a Bash en OS X 10.3 “Panther”. Este cambio no afectó a los sistemas actualizados desde 10.2 o anterior. Los usuarios existentes en esos sistemas convertidos mantuvieron su tcsh concha.

    FreeBSD afirma seguir usando tcsh como shell predeterminado, pero en la máquina virtual FreeBSD 10 que tengo aquí, el shell predeterminado parece ser una de las variantes de shell de Almquist compatibles con POSIX. Esto también es cierto en NetBSD.

    OpenBSD usa una bifurcación de pdksh como 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 en el corto plazo 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 /bin/sh estos días. Tienes que hacer todo lo posible para encontrar algo lo suficientemente parecido para las pruebas de compatibilidad.

    Solo conozco una forma de ejecutar un shell Bourne vintage genuino de 1979 en una computadora moderna:usar las imágenes de disco de Ancient Unix V7 con el simulador SIMH PDP-11 del Computer History Simulation Project. SIMH se ejecuta en casi todas las computadoras modernas, no solo en las tipo Unix. SIMH incluso se ejecuta en Android y en iOS.

    Con OpenSolaris, Sun abrió la versión SVR4 del shell Bourne por primera vez. 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 de Unix.

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

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

    Jörg Schilling ha hecho un mejor trabajo al mantener una versión de este código como obosh en su paquete Schily Tools. Consulte más arriba para obtener 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 juegos de caracteres multibyte, control de tareas, funciones de shell y otras características que no están presentes en el Bourne shell 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 ^ more dará un error en un shell de tipo Korn o POSIX, pero se comportará como ls | more en un verdadero caparazón de Bourne.

  9. De vez en cuando te encuentras con un fish , scsh o rc/es adherentes, pero son aún más raros que los ventiladores de caparazón C.

    El rc La familia de shells no se usa comúnmente en los sistemas Unix/Linux, pero la familia es históricamente importante, por lo que se ganó un lugar en el diagrama anterior. rc es el shell estándar del sistema operativo Plan 9 de Bell Labs, una especie de sucesor de la 10.ª edición de Unix, creado como parte de la investigación continua de Bell Labs sobre el diseño de sistemas operativos. Es incompatible tanto con Bourne como con C shell a nivel de programación; probablemente haya una lección ahí.

    La variante más activa de rc parece ser el mantenido por Toby Goodwin, que se basa en Unix rc clon de Byron Rakitzis.

Relacionado:¿Extraer el archivo de la imagen de la ventana acoplable?
Linux
  1. ¿Qué significa [correo electrónico protegido] en un script de shell?

  2. ¿Qué pasa si [[ $? -ne 0 ]]; significa en .ksh

  3. ¿Qué significa la sintaxis |&en lenguaje shell?

  4. ¿Qué significa #define X X?

  5. ¿Qué significa matar -3?

¿Qué significa chmod 777?

¿Qué significa Ampersand al final de una línea de script de Shell?

¿Qué hace "set -f" en Korn Shell?

¿Qué significa "rm is hash"?

No hay variable X11 DISPLAY - ¿qué significa?

¿Qué significa esta advertencia?