GNU/Linux >> Tutoriels Linux >  >> Linux

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

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

Qu'est-ce que cela signifie pour un shell ou un autre programme d'être "sh compatible" ? 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

J'aimerais toujours une réponse directe à ce que signifie être "sh compatible". Une attente raisonnable pourrait être que "compatible sh" signifie "implémente le langage de commande du shell", mais alors pourquoi y a-t-il tant de shells "compatibles sh" et pourquoi sont-ils différents ?

Réponse acceptée :

Pourquoi y a-t-il tant de shells "compatibles sh" ?

Le shell Bourne a été publié pour la première fois en 1979 dans le cadre d'Unix V7. Étant donné que presque tous les systèmes Unix et de type Unix descendent d'Unix V7 - 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 antérieur, rétronommé le shell Thompson, mais il s'est produit si tôt dans l'histoire d'Unix qu'il est pratiquement oublié aujourd'hui. Le shell Bourne est un sur-ensemble du shell Thompson.²

Les obus Bourne et Thompson étaient appelés sh . Le shell spécifié par POSIX est également appelé sh . Donc, quand quelqu'un dit sh -compatibles, ils font référence à cette série de coques. S'ils voulaient être précis, ils diraient "shell POSIX" ou "shell Bourne".³

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

Cela dit, le shell Korn - en tant que chose distincte du shell POSIX - n'est jamais vraiment devenu populaire en dehors du monde Unix commercial. C'est parce que son essor correspondait aux premières années de la commercialisation d'Unix, il s'est donc retrouvé pris dans les guerres Unix. Les Unix BSD l'ont évité en faveur du shell C, et son code source n'était pas librement disponible pour une utilisation sous Linux lorsqu'il a démarré.⁵ Ainsi, lorsque les premiers distributeurs Linux ont cherché un shell de commande pour aller avec leur noyau Linux, ils ont généralement choisi GNU Bash, l'un de ces sh -compatibles dont vous parlez.⁶

Cette association précoce entre Linux et Bash a pratiquement scellé le sort de nombreux autres shells, y compris ksh , csh et tcsh . Il y a des inconditionnels qui utilisent encore ces obus aujourd'hui, mais ils sont très minoritaires.⁷

Toute cette histoire explique pourquoi les créateurs de retardataires relatifs aiment bash , zsh , et yash a choisi de les faire sh -compatible :la compatibilité Bourne/POSIX est le minimum qu'un shell pour les systèmes de type Unix doit fournir afin d'être largement adopté.

Dans de nombreux systèmes, le shell de commande interactif par défaut et /bin/sh sont des choses différentes. /bin/sh peut être :

  • La coque Bourne d'origine. Ceci est courant dans les anciens systèmes UNIX®, tels que Solaris 10 (sorti en 2005) et ses prédécesseurs.⁸

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

  • La coquille d'Almquist . Il s'agit d'un clone de shell Bourne/POSIX open source initialement publié sur Usenet en 1989, qui a ensuite été contribué au CSRG de Berkeley pour être inclus dans la première version BSD ne contenant pas de 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 est devenu à son tour la base de tous les dérivés BSD modernes, avec /bin/sh restant comme un dérivé d'Almquist dans la plupart d'entre eux, avec une exception majeure notée ci-dessous. Vous pouvez voir cette descendance directe dans les dépôts de code source pour NetBSD et FreeBSD :ils livraient un dérivé du shell Almquist depuis le premier jour.

    Il y a deux éléments ash importants fourches en dehors du monde BSD :

    1. dash , célèbre adopté par Debian et Ubuntu en 2006 comme /bin/sh par défaut la mise en oeuvre. (Bash reste l'interactif par défaut shell de commande dans les dérivés de Debian.)

    2. La ash commande dans BusyBox, qui est fréquemment utilisée dans les Linux embarqués et peut être utilisée pour implémenter /bin/sh . Puisqu'il est postérieur au dash et il a été dérivé de l'ancien ash de Debian package, j'ai choisi de le considérer comme un dérivé de dash plutôt que ash , malgré son nom de commande dans BusyBox.

      (BusyBox inclut également une alternative moins fonctionnelle à ash appelé hush . En règle générale, un seul des deux sera intégré dans un binaire BusyBox donné :ash par défaut, mais hush quand l'espace est vraiment restreint. Ainsi, /bin/sh sur les systèmes basés sur BusyBox n'est pas toujours dash -comme.)

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

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

  • Un shell avec ksh93 Extensions POSIX , comme dans OpenBSD. Bien que le shell OpenBSD change de comportement pour éviter les incompatibilités syntaxiques et sémantiques avec les shells Bourne et POSIX lorsqu'il est appelé en tant que sh , il ne désactive aucune de ses extensions pures, étant celles qui n'entrent pas en conflit avec les anciens shells.

    Ce n'est pas courant; vous ne devriez pas vous attendre à ksh93 fonctionnalités dans /bin/sh .

J'ai utilisé "script shell" ci-dessus comme terme générique signifiant script shell Bourne/POSIX. Cela est dû à l'omniprésence des coquillages de la famille Bourne. Pour parler de script sur d'autres shells, vous devez donner un qualificatif, comme "script shell 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 en compatibles avec le shell Bourne, compatibles avec le shell C et "autres".

Connexe :Commande conviviale pour répertorier tous les utilisateurs sur le système Ubuntu ?

Ce schéma peut vous aider :

(Cliquez pour obtenir la version SVG, 31 ko, ou affichez la version PNG en taille réelle, 218 ko.)

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

Quelqu'un parle d'un sh - chose incompatible signifie généralement l'une des trois choses suivantes :

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

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

  3. Ils parlent d'une caractéristique spécifique dans un shell de la famille Bourne qui n'est pas dans tous les autres shells de la famille Bourne. ksh93 , bash , et zsh en particulier, ont de nombreuses fonctionnalités qui n'existent pas dans les anciens shells "standard". Ces trois éléments sont également mutuellement incompatibles à bien des égards, une fois que vous avez dépassé le partage POSIX/ksh88 socle.

C'est une erreur classique d'écrire un script shell avec un #!/bin/sh ligne shebang en haut mais pour utiliser les extensions de shell Bash ou Korn à l'intérieur. Depuis /bin/sh est l'un des shells du diagramme de la famille Korn/POSIX ci-dessus sur tant de systèmes de nos jours, de tels scripts fonctionneront sur le système sur lequel ils sont écrits, mais échoueront ensuite sur les systèmes où /bin/sh est quelque chose de la famille plus large des coquillages Bourne. La meilleure pratique consiste à utiliser #!/bin/bash ou #!/bin/ksh lignes shebang 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 checkbashisms dessus, un outil du projet Debian qui vérifie un script pour "bashisms".

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

  • Exécutez-le sous obosh du projet Schily Tools, une version améliorée du shell Bourne en open source par Sun dans le cadre d'OpenSolaris 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 inclut également bosh , un shell de type POSIX avec de nombreuses fonctionnalités non standard, mais qui peut être utile pour tester la compatibilité des scripts shell destinés à s'exécuter sur tous les shells de la famille POSIX. Il a tendance à être plus conservateur dans son ensemble de fonctionnalités que bash , zsh et les versions améliorées de ksh93 .

    Schily Tools inclut également un shell appelé bsh , mais c'est une bizarrerie historique qui n'est pas du tout une coquille de la famille Bourne.

  • Parcourez le chapitre Portable Shell Programming 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, tous les « nouveaux et améliorés ! » les choses sont différentes :

  • La version améliorée ne pouvait être améliorée qu'en cassant la rétrocompatibilité.

  • Quelqu'un a pensé à une façon différente de faire fonctionner quelque chose, qu'il préfère, mais qui n'est pas la même que l'ancienne.

  • Quelqu'un a essayé de réimplémenter une ancienne norme sans la comprendre complètement, alors il a tout gâché et a créé une différence involontaire.

Notes de bas de page et apartés :

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

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

    (La ligne 2BSD s'est transformée en un fork parallèle de BSD pour les mini-ordinateurs PDP de Digital, tandis que les lignes 3BSD et 4BSD ont continué à tirer parti des nouveaux types d'ordinateurs comme les stations de travail Vaxen et Unix. 2.9BSD était essentiellement la version PDP de 4.1cBSD; ils étaient code contemporain et partagé. Les PDP n'ont pas simplement disparu lorsque le VAX est arrivé, la ligne 2BSD est donc toujours en train de traîner.)

    Il est sûr 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 eu un système de fichiers hiérarchique cette année-là (awww, comme c'est mignon !) et le premier Macintosh 24 bits avec son écran 9″ N&B — pas en niveaux de gris, littéralement noir et blanc — ne sortira pas avant le début de l'année prochaine.

  2. La coque Thompson était assez primitive selon les normes d'aujourd'hui. Ce n'était qu'un shell de commande interactif, plutôt que l'environnement de programmation de scripts que nous attendons aujourd'hui. Il comportait des éléments tels que les canaux et la redirection d'E / S, 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 obtient d'Unix.

    Le shell Bourne a également remplacé le shell PWB, qui a ajouté des éléments importants au shell Thompson comme la programmabilité (if , switch et while ) et une première forme de variables d'environnement. Le shell PWB est encore moins connu que le shell Thompson car il ne faisait pas partie de toutes les versions d'Unix.

  3. Quand quelqu'un n'est pas spécifique sur la compatibilité POSIX vs Bourne Shell, il y a toute une gamme de choses qu'ils pourraient signifier.

    À un extrême, ils pourraient utiliser l'obus Bourne de 1979 comme référence. Un "sh -script compatible" dans ce sens signifierait qu'il devrait fonctionner parfaitement sur le véritable shell Bourne ou l'un de ses successeurs et clones :ash , bash , ksh , zsh , etc.

    Quelqu'un à l'autre extrême suppose le shell spécifié par POSIX comme référence à la place. Nous prenons tellement de fonctionnalités du shell POSIX comme "standard" de nos jours 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, édition de la ligne de commande, le $() forme de substitution de commande, etc.

  4. Bien que le shell Korn ait des racines remontant au début des années 1980, AT&T ne l'a pas livré sous Unix avant la version 4 de System V en 1988. Comme de nombreux Unix commerciaux sont basés sur SVR4, cela a mis ksh dans à peu près tous les Unix commerciaux pertinents à partir de la fin des années 1980.

    (Quelques saveurs Unix étranges basées sur SVR3 et antérieures ont conservé des parts du marché après la sortie de SVR4, mais elles ont été les premières contre le mur lorsque la révolution est arrivée.)

    1988 est également l'année de la sortie 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. Étant donné que POSIX a effectivement cloué l'original en place, ksh divisé en deux versions majeures :ksh88 et ksh93 , du nom des années impliquées dans leur séparation.

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

    ksh93 est un sur-ensemble entièrement compatible du shell POSIX. Développement sur ksh93 a été sporadique depuis que le référentiel source principal est passé d'AT&T à GitHub, la dernière version datant d'environ 3 ans au moment où j'écris ceci, ksh93v. (Le nom de base du projet reste ksh93 avec des suffixes ajoutés pour indiquer les versions postérieures à 1993.)

    Les systèmes qui incluent un shell Korn en tant que chose distincte du shell POSIX le rendent généralement disponible en tant que /bin/ksh , bien qu'il se cache parfois ailleurs.

    Quand on parle de ksh ou le shell Korn par son nom, nous parlons de ksh93 caractéristiques qui le distinguent de ses sous-ensembles de shell Bourne et POSIX rétrocompatibles. Vous rencontrez rarement le pur ksh88 aujourd'hui.

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

    Pourquoi les premiers fournisseurs Linux choisissent le plus souvent GNU Bash plutôt que pdksh , qui était disponible au moment où Linux a commencé, je suppose que c'est parce qu'une grande partie du reste de l'espace utilisateur provenait également du projet GNU. Bash est également un peu plus avancé que pdksh , puisque les développeurs de Bash ne se limitent pas à copier les fonctionnalités du shell Korn.

    Travailler sur pdksh s'est arrêté à peu près au moment où AT&T a publié le code source sur le véritable shell Korn. Il y a cependant deux fourches principales qui sont toujours maintenues :OpenBSD pdksh et le shell MirBSD Korn, mksh .

    Je trouve intéressant que mksh est la seule implémentation du shell Korn actuellement packagée pour Cygwin.

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

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

    Étant une variante de 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 tcsh à Bash sous 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 tcsh coque.

    FreeBSD prétend toujours utiliser tcsh comme 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. C'est également vrai sur NetBSD.

    OpenBSD utilise un fork de pdksh comme shell par défaut à la place.

    La plus grande popularité de Linux et d'OS X fait que certaines personnes souhaitent que FreeBSD passe également à Bash, mais elles ne le feront pas de si tôt 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 vanille comme /bin/sh ces jours-ci. Vous devez faire tout votre possible pour trouver quelque chose de suffisamment proche pour les tests de compatibilité.

    Je ne connais qu'une seule façon d'exécuter un véritable shell Bourne vintage de 1979 sur un ordinateur moderne :utiliser les images de disque Ancient Unix V7 avec le simulateur SIMH PDP-11 du Computer History Simulation Project. SIMH fonctionne sur à peu près tous les ordinateurs modernes, pas seulement ceux de type Unix. SIMH fonctionne même sur Android et sur 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 possédaient une licence de code source Unix.

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

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

    Jörg Schilling a fait un meilleur travail en maintenant une version de ce code en tant que obosh dans son pack Schily Tools. Voir ci-dessus pour plus d'informations à ce sujet.

    Gardez à l'esprit que ces shells dérivés de la version 2005 du code source contiennent la prise en charge des jeux de caractères multi-octets, le contrôle des tâches, les fonctions shell et d'autres fonctionnalités non présentes dans le shell Bourne original de 1979.

    Une façon de savoir si vous êtes sur un shell Bourne d'origine 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 une commande comme ls ^ more donnera une erreur sur un shell de type Korn ou POSIX, mais il se comportera comme ls | more sur un véritable obus Bourne.

  9. Occasionnellement, vous rencontrez un fish , scsh ou rc/es adhérents, mais ils sont encore plus rares que les fans de C shell.

    Le rc La famille de shells n'est pas couramment utilisée sur les systèmes Unix/Linux, mais la famille est historiquement importante, c'est ainsi qu'elle a gagné une place dans le diagramme ci-dessus. rc est le shell standard du système d'exploitation Plan 9 des Bell Labs, une sorte de successeur de la 10e édition d'Unix, créé dans le cadre des recherches continues des Bell Labs sur la conception des systèmes d'exploitation. Il est incompatible avec Bourne et C shell au niveau de la programmation ; il y a probablement une leçon là-dedans.

    La variante la plus active de rc semble être celui maintenu par Toby Goodwin, qui est basé sur Unix rc clone par Byron Rakitzis.

En relation :Extraire le fichier de l'image Docker ?
Linux
  1. Que signifie cet avertissement ?

  2. Que fait si [[ $ ? -ne 0 ]] ; signifie en .ksh

  3. Qu'est-ce que cela signifie par #define X X ?

  4. Que signifie tuer -3 ?

  5. Que fait % dans les chaînes du shell Linux ?

Que signifie chmod 777

Que signifie `chown Root.root $file` ?

Pas de variable DISPLAY X11 - qu'est-ce que cela signifie ?

Que signifie [email protected] dans un script shell ?

Que signifie la syntaxe |&en langage shell ?

Que signifie %st en haut ?