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?
shell
compatibility
Praxeolítico
fuente
fuente
sh
). Para un shell diferente, se refiere a si ese shell puede ejecutar scripts de shell Bourne.Respuestas:
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 llamash
. Entonces, cuando alguien dice "sh
compatible", 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
ksh
es 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
,csh
ytcsh
. 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
,zsh
yyash
decidieron hacerlossh
compatibles: 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
tal 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/sh
permaneciendo 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
ash
tenedores importantes fuera del mundo BSD:dash
, adoptada por Debian y Ubuntu en 2006 como la/bin/sh
implementación predeterminada . (Bash sigue siendo el shell de comando interactivo predeterminado en los derivados de Debian).El
ash
comando en BusyBox , que se usa con frecuencia en Linux embebidos y se puede usar para implementar/bin/sh
. Ya que es posteriordash
y que se deriva de edad de Debianash
paquete , he elegido para considerarlo un derivado deldash
lugar deash
, a pesar de su nombre de la orden dentro de BusyBox.(BusyBox también incluye una alternativa menos funcional a la
ash
llamadahush
. Por lo general, solo uno de los dos se integrará en cualquier binario de BusyBox:ash
de forma predeterminada, perohush
cuando el espacio es realmente limitado. Por lo tanto,/bin/sh
en los sistemas basados en BusyBox no siempre esdash
similar).GNU Bash , que deshabilita la mayoría de sus extensiones que no son POSIX cuando se llama como
sh
.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
ksh93
extensiones 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 llamash
, 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
ksh93
caracterí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:
(Haga clic para ver la versión SVG, 31 kB, o ver la versión PNG a tamaño completo , 218 kB).
Alguien que habla de
sh
algo incompatible generalmente significa una de tres cosas:Se refieren a uno de esos "otros" proyectiles.
Están haciendo una distinción entre las familias de shell Bourne y C.
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
,bash
yzsh
en 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 /ksh88
base 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/sh
es 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/sh
hay algo de la familia de shells Bourne más amplia. La mejor práctica es utilizar#!/bin/bash
o#!/bin/ksh
Shebang 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
posh
un 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
osh
desde 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
bosh
un 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 quebash
,zsh
y las versiones mejoradas deksh93
.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 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 :
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.
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
,switch
ywhile
) 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.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 "
sh
secuencia 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.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ó
ksh
casi 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,
ksh
bifurcado en dos versiones principales:ksh88
yksh93
, nombrado después de los años involucrados en su división.ksh88
no es totalmente compatible con POSIX, aunque las diferencias son pequeñas, por lo que algunas versiones delksh88
shell 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).ksh93
es un superconjunto totalmente compatible del shell POSIX . El desarrollo enksh93
ha 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 permaneceksh93
con 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
ksh
el shell Korn por su nombre, estamos hablando deksh93
características que lo distinguen de sus subconjuntos de shell Bourne y POSIX compatibles con versiones anteriores. Raramente te encuentras con lo puroksh88
hoy.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 quepdksh
, ya que los desarrolladores de Bash no se limitan a copiar las características del shell Korn.El trabajo se
pdksh
detuvo aproximadamente cuando AT&T lanzó el código fuente al verdadero shell Korn. Hay dos horquillas principales que se siguen manteniendo, sin embargo: la OpenBSDpdksh
y el Korn Shell MirBSD,mksh
.Me parece interesante que
mksh
sea la única implementación de shell Korn actualmente empaquetada para Cygwin.GNU Bash va más allá de POSIX de muchas maneras, pero puede pedirle que se ejecute en un modo POSIX más puro .
csh
/tcsh
solía ser el shell interactivo predeterminado en BSD Unixes a principios de los 90Siendo 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
tcsh
Bash 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 sutcsh
shell.FreeBSD afirma que todavía se usa
tcsh
como 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
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 pronto por razones filosóficas . Es fácil cambiarlo , si esto te molesta.
Es raro encontrar un sistema con un shell Bourne verdaderamente vainilla como en
/bin/sh
estos 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
osh
en 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 comols ^ more
dará un error en un shell de tipo Korn o POSIX, pero se comportará comols | more
en un shell Bourne verdadero.De vez en cuando te encuentras con un
fish
,scsh
orc/es
adherente, pero son aún más raros que los fanáticos de C.La
rc
familia 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.rc
es 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
rc
parece ser la mantenida por Toby Goodwin , que se basa en elrc
clon Unix de Byron Rakitzis.fuente
"sh compatible" se refiere a POSIX
sh
, 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/sh
es un enlace simbólico/bin/bash
, lo que ha permitido que algunos se deslizan en bash scripts que se declaran a utilizarsh
con#!/bin/sh
. Estos scripts no funcionan en sistemas que no se usanbash
como/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 predeterminadosh
ú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 supuestossh
guiones. 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
bash
ytcsh
y enzsh
todos 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 lash
implementació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
bash
lugar desh
: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 usansh
y se adhieren al lenguaje de comandos de la base shell.fuente