Qu'est-ce que cela signifie d'être "compatible sh"?

63

J'ai vu l'expression "sh compatible" utilisée habituellement en référence aux coquillages. Je ne sais pas si cela s'applique également aux programmes pouvant être exécutés à partir de shells.

Qu'est-ce que cela signifie pour un shell ou un autre programme d'être "compatible sh"? Qu'est-ce que cela signifierait d'être "sh incompatible"?

Edit: Cette question demandant la différence entre bash et sh est très pertinente: Différence entre sh et bash

Je voudrais toujours une réponse directe à ce que signifie être "compatible sh". Une attente raisonnable pourrait être que "sh compatible" signifie "implémente le langage de commande Shell", mais alors pourquoi existe-t-il autant de shells "compatibles" et pourquoi sont-ils différents?

Praxéolitique
la source
1
Pour un script shell, cela signifie si ce script utilise ou non une syntaxe compatible avec le shell Bourne ( sh). Pour un shell différent, cela indique si ce shell peut ou non exécuter les scripts du shell Bourne.
HalosGhost
Si vous voulez apprendre l' inventeur de coquillages , vous pouvez visiter ma réponse à unix.stackexchange.com/questions/45684/...
Golfe Persique

Réponses:

116

Pourquoi y a-t-il tant d'obus "compatibles"?

Le shell Bourne a été publié pour la première fois en 1979 sous Unix V7 . Étant donné que pratiquement tous les systèmes Unix et de type Unix descendent de la V7 Unix - même si ce n’est que spirituellement - le shell Bourne est avec nous "pour toujours".

Le shell Bourne a en fait remplacé un shell précédent, il est devenu le shell Thompson , mais cela s'est passé si tôt dans l'histoire d'Unix que tout est oublié aujourd'hui. La coque Bourne est un sur-ensemble de la coque Thompson

Les obus Bourne et Thompson ont été appelés sh. Le shell spécifié par POSIX est également appelé sh. Ainsi, lorsque quelqu'un dit « shcompatible», il fait référence à cette série d'obus. S'ils voulaient être précis, ils diraient "shell POSIX" ou "shell Bourne".

Le shell POSIX est basé sur la version de 1988 de KornShell , qui devait à son tour remplacer le shell Bourne sous AT & T Unix, dépassant ainsi le shell BSD C en termes de fonctionnalités. »Dans la mesure où kshcet ancêtre est le shell POSIX, la plupart Les systèmes Unix et de type Unix incluent une variante du shell Korn aujourd'hui. Les exceptions sont généralement des systèmes embarqués minuscules, qui ne peuvent pas se permettre l'espace nécessaire à un shell POSIX complet.

Cela dit, la coquille Korn - en tant que chose distincte de la coquille POSIX - n'est jamais vraiment devenue populaire en dehors du monde commercial Unix. Ceci est dû au fait que son ascension correspond aux premières années de la commercialisation d’Unix et qu’il a donc été pris dans les guerres d’Unix . BSD Unixes l’évitait en faveur du shell C, et son code source n’était pas librement disponible pour l’utilisation de Linux lorsqu’il a été lancé. »Ainsi, lorsque les premiers distributeurs Linux ont cherché un shell de commande pour leur noyau Linux, ils ont généralement choisi GNU Bash , l’une de ces shincompatibles dont vous parlez. »

Cette association précoce entre Linux et Bash a en quelque sorte scellé le destin de nombreux autres shell, y compris ksh, cshet tcsh. Il y a des durs qui utilisent encore ces coquilles aujourd'hui, mais ils sont très minoritaires. »

Toute cette histoire explique pourquoi les créateurs de retardataires relatifs aiment bash, zshet ont yashchoisi de les rendre shcompatibles: la compatibilité Bourne / POSIX est le minimum qu'un shell pour les systèmes de type Unix doit fournir pour une adoption généralisée.

Dans de nombreux systèmes, le shell de commande interactif par défaut /bin/shest différent. /bin/shpeut être:

  • Le shell original Bourne. Ceci est courant dans les anciens systèmes UNIX®, tels que Solaris 10 (publié en 2005) et ses prédécesseurs.

  • Un shell certifié POSIX. Ceci est courant dans les systèmes UNIX® plus récents, tels que Solaris 11 (2010).

  • La coquille Almquist . Il s'agit d'un clone open source Bourne / POSIX publié à l'origine sur Usenet en 1989 , qui a ensuite été transféré au CSRG de Berkeley pour inclusion dans la première version BSD ne contenant aucun code source AT & T, 4.4BSD-Lite . Le shell Almquist est souvent appelé ash, même lorsqu'il est installé en tant que /bin/sh.

    4.4BSD-Lite devint à son tour la base de tous les dérivés BSD modernes, /bin/shrestant dans la plupart des cas un dérivé d'Almquist, à une exception près indiquée ci-dessous. Vous pouvez voir cette descendance directe dans les référentiels de code source de NetBSD et FreeBSD : ils livraient un dérivé du shell Almquist dès le premier jour.

    Il y a deux ashfourchettes importantes en dehors du monde BSD:

    1. dash, adoptée par Debian et Ubuntu en 2006 en tant qu’implémentation par défaut /bin/sh. (Bash reste le shell de commande interactif par défaut dans les dérivés de Debian.)

    2. La ashcommande dans BusyBox , qui est fréquemment utilisée dans les Linux embarqués et peut être utilisée pour être implémentée /bin/sh. Depuis qu'il date dashet qu'il est dérivé de l'ancien ashpaquet Debian , j'ai choisi de le considérer comme un dérivé de dashplutôt que ash, malgré le nom de sa commande dans BusyBox.

      (BusyBox inclut également une alternative moins fonctionnelle à ashappelé hush. Généralement, un seul des deux est construit dans un binaire donné de BusyBox: ashpar défaut, mais hushlorsque l'espace est vraiment restreint. Ainsi, /bin/shsur les systèmes basés sur BusyBox, ce n'est pas toujours dashsemblable.)

  • GNU Bash , qui désactive la plupart de ses extensions non-POSIX lorsqu'il est appelé en tant quesh .

    Ce choix est typique des variantes de serveur et de bureau de Linux, à l’exception de Debian et de ses dérivés. Mac OS X l’a également fait depuis Panther, sorti en 2003.

  • Un shell avec ksh93des extensions POSIX , comme dans OpenBSD . Bien que le shell OpenBSD change de comportement pour éviter les incompatibilités sémantiques et de syntaxe avec les shells Bourne et POSIX lorsqu’il est appelé sh, il ne désactive aucune de ses extensions pures, c’est-à-dire celles qui ne sont pas en conflit avec des shells plus anciens.

    Ce n'est pas commun. vous ne devriez pas vous attendre à des ksh93fonctionnalités dans /bin/sh.

J'ai utilisé le terme "script shell" ci-dessus comme terme générique qui signifie "script shell Bourne / POSIX". Cela est dû à l'omniprésence des coquillages de la famille Bourne. Pour parler de la création de scripts sur d'autres shells, vous devez donner un qualificatif, tel que "script C". Même sur les systèmes où un shell de la famille C est le shell interactif par défaut, il est préférable d'utiliser le shell Bourne pour les scripts.

Il est révélateur que, lorsque Wikipédia classe les shells Unix , ils les regroupent entre Bourne shell compatible, C shell compatible et "autre".

Ce diagramme peut aider:

Les shells Unix: familles Shell Bourne, Korn, POSIX, C et rc

(Cliquez pour la version SVG, 31 Ko, ou pour voir la version PNG en taille réelle , 218 Ko.)

Qu'est-ce que cela signifierait d'être "sh incompatible"?

Quelqu'un qui parle d'une shchose incompatible est généralement l'une des trois choses suivantes:

  1. Ils font référence à l'un de ces "autres" coquilles.

  2. Ils font une distinction entre les familles Bourne et C shell.

  3. Ils parlent d'une caractéristique spécifique dans une coquille de la famille Bourne qui n'est pas dans toutes les autres coquilles de la famille Bourne. ksh93, bashet zshnotamment de nombreuses fonctionnalités qui n'existaient pas dans les anciens shells "standard". Ces trois systèmes sont également incompatibles à bien des égards, une fois que vous avez dépassé la ksh88base POSIX / partagée .

C'est une erreur classique d'écrire un script shell avec une #!/bin/sh ligne shebang en haut, mais d'utiliser des extensions shell Bash ou Korn à l'intérieur. Étant donné qu’il /bin/shs’agit de l’un des shells du diagramme de la famille Korn / POSIX présenté ci-dessus sur de nombreux systèmes, ces scripts fonctionnent sur le système sur lequel ils sont écrits, mais échouent ensuite sur les systèmes /bin/shappartenant à la famille de shells Bourne. La meilleure pratique consiste à utiliser #!/bin/bashou à #!/bin/kshrelier des lignes si le script utilise de telles extensions.

Il existe de nombreuses façons de vérifier si un script shell de la famille Bourne est portable:

  • Exécutez- checkbashismsle, un outil du projet Debian qui vérifie les " bashismes " d'un script .

  • Exécutez-le sous posh, un shell dans le référentiel de paquets Debian qui implémente à dessein uniquement les fonctionnalités spécifiées par SUS3 , ainsi que quelques autres fonctionnalités mineures .

  • Exécutez-le dans le cadre oshdu projet Schily Tools , une version améliorée du shell Bourne d’OpenSolaris développé par Sun en 2005, ce qui en fait l’un des moyens les plus simples d’obtenir un shell Bourne de style 1979 sur un ordinateur moderne.

    La distribution Schily Tools comprend également boshun shell de type POSIX avec de nombreuses fonctionnalités non standard , mais qui peut être utile pour tester la compatibilité des scripts de shell destinés à être exécutés sur tous les shells de la famille POSIX. Il a tendance à être plus conservateur dans ses fonctionnalités que bashdans zshles versions améliorées de ksh93.

    Schily Tools inclut également un shell appelé bsh, mais il s’agit d’ une curiosité historique qui n’est pas du tout un shell de la famille Bourne.

  • Parcourez le chapitre Programmation de shell portable du manuel GNU Autoconf . Vous pouvez reconnaître certaines des constructions problématiques dont il parle dans vos scripts.

Pourquoi sont-ils différents?

Pour les mêmes raisons, tout "Nouveau et amélioré!" les choses sont différentes:

  • La version améliorée ne pourrait être améliorée qu'en supprimant la compatibilité ascendante.

  • Quelqu'un a pensé à une manière différente de travailler, quelque chose qu’elle préfère, mais qui n’est pas la même chose que l’ancienne.

  • Quelqu'un a essayé de réimplémenter un ancien standard sans le comprendre parfaitement. Ils ont donc tout gâché et créé une différence non intentionnelle.


Notes de bas de page et de côté :

  1. Les premières versions de BSD Unix n'étaient que des collections de logiciels complémentaires pour V6 Unix. Etant donné que le shell Bourne n’a été ajouté à AT & T Unix qu’après la V7, BSD n’a pas techniquement commencé avec le shell Bourne. La réponse de BSD à la nature primitive de la coquille Thompson était la coque C .

    Néanmoins, les premières versions autonomes de BSD (et de 2.9BSD 3BSD) étaient basées sur V7 ou son successeur portable UNIX / 32V , donc ils l'ont fait inclure le shell Bourne.

    (La ligne 2BSD transformé en une fourchette parallèle de BSD pour de Digital de mini - ordinateurs PDP , tandis que les lignes 3BSD et 4BSD ont continué à tirer profit des types d'ordinateurs plus récents comme VAX et les stations de travail Unix 2.9BSD était essentiellement la version PDP de 4.1cBSD;. Ils étaient contemporaine, et le code partagé . PDPs ne disparaissent pas lorsque le VAX est arrivé, de sorte que la ligne 2BSD est toujours traînante le long .)

    Il est juste de dire que le shell Bourne était partout dans le monde Unix en 1983. C'est une bonne approximation de "pour toujours" dans l'industrie informatique. MS-DOS a obtenu un système de fichiers hiérarchique cette année-là (ainsi que le premier Macintosh 24 bits avec son écran 9 "N & B - ni en niveaux de gris, ni en noir et blanc - ne sortira pas avant le début de l'année prochaine.

  2. La coquille Thompson était assez primitive par rapport aux normes actuelles. Ce n'était qu'un shell de commande interactif, plutôt que l'environnement de programmation de script que nous attendons aujourd'hui. Il contenait des éléments tels que les tuyaux et la redirection d'entrée / sortie, que nous considérons comme faisant partie du prototype d'un "shell Unix", de sorte que nous pensons que le shell de commande MS-DOS les extrait d'Unix.

    Le shell Bourne a également remplacé le shell PWB , ce qui a ajouté des éléments importants au shell Thompson, tels que la programmabilité ( if, switchet while) et une forme précoce de variables d’environnement. Le shell PWB est encore moins connu que le shell Thompson puisqu'il ne faisait pas partie de toutes les versions d'Unix.

  3. Lorsque quelqu'un n'est pas spécifique à propos de la compatibilité entre le shell POSIX et Bourne, il peut entendre toute une gamme de choses.

    À un extrême, ils pourraient utiliser le Bourne 1979 comme base de référence. Un « shscénario compatible » dans ce sens signifierait qu'il devrait fonctionner parfaitement sur la coquille vraie Bourne ou l' un de ses successeurs et clones: ash, bash, ksh, zsh, etc.

    À l’autre extrémité, une personne assume le shell spécifié par POSIX comme référence. De nos jours, nous prenons tellement de fonctionnalités "standard" dans le shell POSIX que nous oublions souvent qu’elles n’étaient pas réellement présentes dans le shell Bourne: arithmétique intégrée, contrôle des tâches, historique des commandes, alias, modification de ligne de commande, $()forme de commande substitution, etc.

  4. Bien que le shell Korn ait des racines remontant au début des années 1980, AT & T ne l’a pas expédié sous Unix jusqu’à System V Release 4 en 1988. Étant donné que tant d’Unix commerciaux sont basés sur SVR4, cela inclut kshpratiquement tous les Unix commerciaux pertinents du fabricant. fin des années 1980.

    (Quelques saveurs Unix étranges basées sur SVR3 et antérieures se sont maintenues sur des morceaux du marché après la sortie de SVR4, mais elles étaient les premières contre le mur lorsque la révolution est survenue.)

    1988 est également l'année de la publication du premier standard POSIX , avec son "shell POSIX" basé sur le shell Korn. Plus tard, en 1993, une version améliorée du shell Korn est sortie. Depuis que POSIX a efficacement cloué l’original en place, il a kshété divisé en deux versions majeures: ksh88et ksh93, du nom des années impliquées dans leur scission.

    ksh88n'est pas entièrement compatible POSIX, bien que les différences soient minimes, de sorte que certaines versions du ksh88shell ont été corrigées pour être compatibles POSIX. (Ceci est tiré d'une interview intéressante sur Slashdot avec le Dr. David G. Korn . Oui, le gars qui a écrit la coquille.)

    ksh93est un sur-ensemble entièrement compatible du shell POSIX . Le développement sur ksh93a été sporadique depuis que le référentiel source principal a été transféré d’AT & T à GitHub, la version la plus récente datant d’environ 3 ans, ksh93v. (Le nom de base du projet reste ksh93avec des suffixes ajoutés pour indiquer les versions publiées au-delà de 1993.)

    Les systèmes qui incluent un shell Korn en tant que composant distinct du shell POSIX le rendent généralement disponible /bin/ksh, même si parfois il se cache ailleurs.

    Lorsque nous parlons de nom kshou de shell Korn, nous parlons de ksh93fonctionnalités qui le distinguent des sous-ensembles de shell Bourne et POSIX rétrocompatibles. Vous rencontrez rarement le pur ksh88aujourd'hui.

  5. AT & T a conservé le code source du shell Korn jusqu'en mars 2000 . À ce stade, l'association de Linux avec GNU Bash était très forte. Bash et ksh93 chacun ont des avantages sur l’autre , mais à ce stade, l’inertie maintient Linux étroitement associé à Bash.

    Quant aux raisons pour lesquelles les premiers fournisseurs de Linux optaient le plus souvent pour GNU Bash pdksh, qui était disponible au moment du démarrage de Linux, je suppose que c'est parce qu'une grande partie du reste de l'espace utilisateur provient également du projet GNU . Bash est également un peu plus avancé que celui-ci pdksh, car les développeurs de Bash ne se limitent pas à la copie des fonctionnalités du shell Korn.

    Les travaux ont pdkshcessé à peu près au moment où AT & T a publié le code source dans le véritable shell Korn. Il y a deux fourches principales qui sont encore maintenus, cependant: OpenBSD pdkshet le MirBSD Korn Shell,mksh .

    Je trouve intéressant que ce mkshsoit la seule implémentation de shell Korn actuellement intégrée dans Cygwin.

  6. GNU Bash va au-delà de POSIX à bien des égards, mais vous pouvez lui demander de fonctionner dans un mode POSIX plus pur .

  7. csh/ tcshétait généralement le shell interactif par défaut de BSD Unix au début des années 1990.

    En tant que variante BSD , les premières versions de Mac OS X étaient ainsi, via Mac OS X 10.2 "Jaguar" . OS X a changé le shell par défaut de tcshBash dans OS X 10.3 "Panther" . Cette modification n'a pas affecté les systèmes mis à niveau à partir de la version 10.2 ou antérieure. Les utilisateurs existants sur ces systèmes convertis ont conservé leur tcshshell.

    FreeBSD prétend continuer à utiliser tcshle shell par défaut , mais sur la machine virtuelle FreeBSD 10 que j'ai ici, le shell par défaut semble être l'une des variantes de shell Almquist compatibles POSIX . Ceci est également vrai sur NetBSD.

    OpenBSD utilise un fork de pdkshcomme shell par défaut.

    La popularité accrue de Linux et OS X incite certaines personnes à souhaiter que FreeBSD passe également à Bash, mais cela ne sera pas le cas pour des raisons philosophiques . Il est facile de le changer si cela vous dérange.

  8. Il est rare de trouver un système avec un shell Bourne vraiment vanillé comme /bin/shces jours-ci. Vous devez faire tout votre possible pour trouver quelque chose d'assez proche pour le test de compatibilité.

    Je ne connais qu'un seul moyen de gérer un véritable shell Bourne de 1979 sur un ordinateur moderne: utilisez les images de disque Ancient Unix V7 avec le simulateur SIMH PDP-11 du projet Computer History Simulation . SIMH fonctionne sur pratiquement tous les ordinateurs modernes , pas seulement ceux de type Unix. SIMH fonctionne même sur Android et iOS .

    Avec OpenSolaris , Sun a ouvert pour la première fois la version SVR4 du shell Bourne. Auparavant, le code source des versions post-V7 du shell Bourne n’était disponible que pour ceux qui détenaient une licence de code source Unix.

    Ce code est maintenant disponible séparément du reste du projet obsolète OpenSolaris à partir de plusieurs sources différentes.

    La source la plus directe est le projet de shell Heirloom Bourne . Cela est devenu disponible peu de temps après la version 2005 d'OpenSolaris. Certains travaux de portabilité et de correction des bogues ont été effectués au cours des prochains mois, mais le développement du projet s’est arrêté.

    Jörg Schilling a fait un meilleur travail en maintenant une version de ce code comme oshdans son paquet Schily Tools . Voir ci-dessus pour plus d'informations à ce sujet.

    N'oubliez pas que ces shells dérivés de l'édition de code source 2005 contiennent un support de jeu de caractères multi-octets , un contrôle des travaux, des fonctions de shell et d'autres fonctionnalités non présentes dans le shell Bourne original de 1979.

    Une façon de savoir si vous utilisez ou non un shell Bourne original est de voir s'il prend en charge une fonctionnalité non documentée ajoutée pour faciliter la transition depuis le shell Thompson: ^comme alias pour |. C'est-à-dire qu'une commande comme ls ^ moreva donner une erreur sur un shell de type Korn ou POSIX, mais se comportera comme ls | moresur un vrai shell Bourne.

  9. Parfois , vous rencontrez un fish, scshou rc/esadhérent, mais ils sont encore plus rares que les fans de shell C.

    La rcfamille de shells n'est pas couramment utilisée sur les systèmes Unix / Linux, mais elle est historiquement importante, ce qui explique sa place dans le diagramme ci-dessus. rcest le shell standard du système d'exploitation Plan 9 de Bell Labs , une sorte de successeur de la 10e édition d'Unix , créé dans le cadre de la recherche continue de Bell Labs sur la conception du système d'exploitation. Il est incompatible avec Bourne et C shell au niveau de la programmation. il y a probablement une leçon dedans.

    La variante la plus active de rcsemble être celle maintenue par Toby Goodwin , basée sur le rcclone Unix de Byron Rakitzis.

Warren Young
la source
Si vous souhaitez connaître davantage de relations, par exemple avec UNOS "commande", "bsh" et le récent Bourne Shell, envoyez-moi une note. Comme indice: la commande UNOS avait une commande intégrée "do" qui agissait comme un script shell à une ligne avec des arguments. Cette idée a été transférée dans Bourne Shell en tant que "dosh" et permet des alias paramétrables, ce que vous ne pouvez pas obtenir de ksh ou de bash.
Schily
Il convient de noter que pdksh lui-même est basé sur le shell Forsyth. Principalement oublié aujourd'hui, il a certes une signification historique dans l'héritage de pdksh, mais aussi dans la mesure où il s'agissait de la coquille de certaines versions de minix et qui avait été porté sur msdos.
Stéphane Chazelas
25

"sh compatible" fait référence à POSIXsh , le shell de base devant exister sur tous les systèmes compatibles. Un script compatible sh devrait fonctionner sur n’importe quel ordinateur compatible POSIX.

La raison pour laquelle il est nécessaire de le dire est qu’il s’agit généralement d’ /bin/shun lien symbolique vers /bin/bash, ce qui a permis à certains Bashism de se glisser dans des scripts qu’ils déclarent utiliser shavec #!/bin/sh. Ces scripts ne fonctionnent pas sur les systèmes qui n'utilisent pas bashas /bin/sh, y compris certains Unices commerciaux pour toujours, et Debian et ses dérivés récemment.

En particulier, il y a eu une tendance à utiliser dash, le shell Debian Almquish, par défaut shces derniers temps, car il est plus petit et plus rapide. Cette tendance a mis en évidence beaucoup de ces Bashism qui étaient dans des shscripts supposés . Décrire quelque chose comme "sh compatible" indique qu'il est explicitement destiné à fonctionner avec ces systèmes en restant entièrement dans le langage spécifié par POSIX - tous les shells implémenteront un sur-ensemble de cette fonctionnalité, ce qui garantit leur fonctionnement partout, mais leurs extensions ne le sont pas. compatibles les uns avec les autres.

Différentes coques ont leur propre historique de développement et ont divergé dans le temps, en ajoutant des fonctions permettant une utilisation interactive pour leurs utilisateurs, ou des extensions de script telles que des tableaux associatifs. Un script "incompatible avec sh" utiliserait certaines de ces fonctionnalités d'extension non standard, telles que les [[conditions de Bash .

Les fonctionnalités non-POSIX dans bashet tcshet zshet dans tous les autres shells actuels sont utiles , et il existe de nombreuses occasions où vous pourriez en avoir besoin ou avoir besoin de celles-ci. Elles ne doivent tout simplement pas être utilisées dans un script qui se déclare lui-même /bin/sh, car vous ne pouvez pas compter sur ces fonctionnalités dans l' shimplémentation de base du système sur lequel vous exécutez.

Un script qui doit utiliser, par exemple, des tableaux associatifs, doit s’assurer qu’il est exécuté avec bashplutôt que sh:

#!/bin/bash
declare -A array

Cela fonctionnera n'importe où avec bash. Les scripts qui n'ont pas besoin de la fonctionnalité étendue et qui sont censés être portables doivent déclarer qu'ils utilisent shet s'en tenir au langage de commande du shell de base.

Michael Homer
la source