GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Was bedeutet es, „sh-kompatibel“ zu sein?

Ich habe gesehen, dass der Ausdruck „sh-kompatibel“ normalerweise in Bezug auf Shells verwendet wird. Ich bin mir nicht sicher, ob es auch für Programme gilt, die von Shells aus ausgeführt werden können.

Was bedeutet es, wenn eine Shell oder ein anderes Programm „sh-kompatibel“ ist? Was würde es bedeuten, „sh inkompatibel“ zu sein?

Bearbeiten:
Diese Frage, die den Unterschied zwischen bash und sh stellt, ist sehr relevant:
Unterschied zwischen sh und bash

Ich hätte immer noch gerne eine direkte Antwort darauf, was es bedeutet, „sh-kompatibel“ zu sein. Eine vernünftige Erwartung könnte sein, dass „sh-kompatibel“ bedeutet „implementiert die Shell-Befehlssprache“, aber warum gibt es dann so viele „sh-kompatible“ Shells und warum unterscheiden sie sich?

Akzeptierte Antwort:

Warum gibt es so viele „sh-kompatible“ Shells?

Die Bourne-Shell wurde erstmals 1979 als Teil von Unix V7 veröffentlicht. Da so ziemlich jedes Unix und Unix-ähnliche System von V7 Unix abstammt – und sei es auch nur in geistiger Hinsicht – hat uns die Bourne-Shell „für immer“ begleitet¹

Die Bourne-Shell ersetzte tatsächlich eine frühere Shell, die als Thompson-Shell bezeichnet wurde, aber sie geschah so früh in der Geschichte von Unix, dass sie heute so gut wie vergessen ist. Die Bourne-Schale ist eine Obermenge der Thompson-Schale.²

Sowohl die Bourne- als auch die Thompson-Shell hießen sh . Die von POSIX spezifizierte Shell wird auch sh genannt . Also, wenn jemand sh sagt -kompatibel, beziehen sie sich handwinkend auf diese Muschelserie. Wenn sie es genau wissen wollten, würden sie „POSIX-Shell“ oder „Bourne-Shell“ sagen.³

Die POSIX-Shell basiert auf der Version von KornShell von 1988, die ihrerseits die Bourne-Shell auf AT&T Unix ersetzen sollte und die BSD-C-Shell in Bezug auf Funktionen überholte.⁴ Soweit ksh der Vorfahre der POSIX-Shell ist, enthalten die meisten Unix- und Unix-ähnlichen Systeme heute eine Variante der Korn-Shell. Ausnahmen sind im Allgemeinen winzige eingebettete Systeme, die sich nicht den Platz leisten können, den eine vollständige POSIX-Shell einnimmt.

Abgesehen davon wurde die Korn-Shell – als etwas, das sich von der POSIX-Shell unterscheidet – außerhalb der kommerziellen Unix-Welt nie wirklich populär. Dies liegt daran, dass sein Aufstieg mit den frühen Jahren der Unix-Kommerzialisierung korrespondierte, sodass es in die Unix-Kriege verwickelt wurde. BSD-Unixes verzichteten darauf zugunsten der C-Shell, und ihr Quellcode war zu Beginn nicht frei für die Verwendung in Linux verfügbar.⁵ Als die frühen Linux-Distributoren also nach einer Befehlsshell suchten, die zu ihrem Linux-Kernel passte, suchten sie Sie wählten normalerweise GNU Bash, eines dieser sh -kompatibel, von denen Sie sprechen.⁶

Diese frühe Assoziation zwischen Linux und Bash besiegelte so ziemlich das Schicksal vieler anderer Shells, einschließlich ksh , csh und tcsh . Es gibt auch heute noch Hartgesottene, die diese Muscheln verwenden, aber sie sind sehr in der Minderheit.⁷

All diese Geschichte erklärt, warum die Schöpfer von relativen Nachzüglern wie bash , zsh , und yash entschied sich dafür, sie sh zu machen -kompatibel:Bourne/POSIX-Kompatibilität ist das Minimum, das eine Shell für Unix-ähnliche Systeme bieten muss, um weit verbreitet zu sein.

In vielen Systemen die standardmäßige interaktive Befehlsshell und /bin/sh sind verschiedene Dinge. /bin/sh kann sein:

  • Die ursprüngliche Bourne-Shell. Dies ist bei älteren UNIX®-Systemen wie Solaris 10 (veröffentlicht 2005) und seinen Vorgängern üblich.⁸

  • Eine POSIX-zertifizierte Shell. Dies ist bei neueren UNIX®-Systemen wie Solaris 11 (2010) üblich.

  • Die Almquist-Muschel . Dies ist ein Open-Source-Bourne/POSIX-Shell-Klon, der ursprünglich 1989 im Usenet veröffentlicht wurde und dann zu Berkeleys CSRG zur Aufnahme in die erste BSD-Veröffentlichung beigetragen wurde, die keinen AT&T-Quellcode enthält, 4.4BSD-Lite. Die Almquist-Shell wird oft als ash bezeichnet , auch wenn es als /bin/sh installiert ist .

    4.4BSD-Lite wiederum wurde mit /bin/sh zur Basis für alle modernen BSD-Derivate bleibt in den meisten von ihnen ein Almquist-Derivat, mit einer großen Ausnahme, die unten erwähnt wird. Sie können diese direkte Nachkommenschaft in den Quellcode-Repositories für NetBSD und FreeBSD sehen:Sie haben vom ersten Tag an ein Almquist-Shell-Derivat ausgeliefert.

    Es gibt zwei wichtige ash Forks außerhalb der BSD-Welt:

    1. dash , bekanntermaßen 2006 von Debian und Ubuntu als Standard /bin/sh übernommen Implementierung. (Bash bleibt die standardmäßige interaktive Befehlsshell in Debian-Derivaten.)

    2. Die ash Befehl in BusyBox, der häufig in eingebetteten Linuxen verwendet wird und zum Implementieren von /bin/sh verwendet werden kann . Da es dash nachdatiert und es wurde von Debians altem ash abgeleitet Paket habe ich mich entschieden, es als Ableitung von dash zu betrachten statt ash , trotz seines Befehlsnamens innerhalb von BusyBox.

      (BusyBox enthält auch eine weniger funktionsreiche Alternative zu ash genannt hush . Typischerweise wird nur einer der beiden in eine gegebene BusyBox-Binärdatei eingebaut:ash standardmäßig, aber hush wenn der Platz wirklich eng ist. Also /bin/sh auf BusyBox-basierten Systemen ist nicht immer dash -ähnlich.)

  • GNU Bash , das die meisten seiner Nicht-POSIX-Erweiterungen deaktiviert, wenn es als sh aufgerufen wird .

    Diese Auswahl ist typisch für Desktop- und Server-Varianten von Linux, mit Ausnahme von Debian und seinen Derivaten. Mac OS X hat dies auch seit Panther getan, das 2003 veröffentlicht wurde.

  • Eine Shell mit ksh93 POSIX-Erweiterungen , wie bei OpenBSD. Obwohl die OpenBSD-Shell ihr Verhalten ändert, um syntaktische und semantische Inkompatibilitäten mit Bourne- und POSIX-Shells zu vermeiden, wenn sie als sh aufgerufen wird , es deaktiviert keine seiner reinen Erweiterungen, da es sich nicht um solche handelt, die nicht mit älteren Shells in Konflikt geraten.

    Dies ist nicht üblich; Sie sollten ksh93 nicht erwarten Funktionen in /bin/sh .

Ich habe „Shell-Skript“ oben als Oberbegriff für Bourne/POSIX-Shell-Skripting verwendet. Dies liegt an der Allgegenwart von Muscheln der Bourne-Familie. Um über Skripting auf anderen Shells zu sprechen, müssen Sie einen Qualifizierer wie „C-Shell-Skript“ angeben. Selbst auf Systemen, auf denen eine Shell der C-Familie die standardmäßige interaktive Shell ist, ist es besser, die Bourne-Shell für das Skripting zu verwenden.

Es ist bezeichnend, dass Wikipedia, wenn es Unix-Shells klassifiziert, sie in Bourne-Shell-kompatibel, C-Shell-kompatibel und „Andere“ gruppiert.

Verwandte:Benutzerfreundlicher Befehl zum Auflisten aller Benutzer auf dem Ubuntu-System?

Dieses Diagramm kann helfen:

(Klicken Sie hier, um die SVG-Version, 31 kB, oder die PNG-Version in voller Größe, 218 kB, anzuzeigen.)

Was würde es bedeuten, „sh inkompatibel“ zu sein?

Jemand spricht über ein sh -inkompatibles Ding bedeutet normalerweise eines von drei Dingen:

  1. Sie beziehen sich auf eine dieser „anderen“ Shells.⁹

  2. Sie unterscheiden zwischen den Bourne- und C-Shell-Familien.

  3. Sie sprechen über ein bestimmtes Feature in einer Shell der Bourne-Familie, das nicht in allen anderen Shells der Bourne-Familie vorhanden ist. ksh93 , bash und zsh haben insbesondere viele Funktionen, die in den älteren „Standard“-Shells nicht vorhanden sind. Diese drei sind auch in vielerlei Hinsicht nicht kompatibel, sobald Sie über das gemeinsame POSIX/ksh88 hinauskommen Basis.

Es ist ein klassischer Fehler, ein Shell-Skript mit einem #!/bin/sh zu schreiben shebang-Zeile oben, aber um Bash- oder Korn-Shell-Erweiterungen darin zu verwenden. Seit /bin/sh ist eine der Shells im Diagramm der Korn/POSIX-Familie oben auf so vielen Systemen heutzutage, dass solche Skripte auf dem System funktionieren, auf dem sie geschrieben wurden, aber dann auf Systemen fehlschlagen, auf denen /bin/sh ist etwas aus der breiteren Familie der Bourne-Muscheln. Best Practice ist die Verwendung von #!/bin/bash oder #!/bin/ksh Shebang-Zeilen, wenn das Skript solche Erweiterungen verwendet.

Es gibt viele Möglichkeiten zu prüfen, ob ein bestimmtes Shell-Skript der Bourne-Familie portierbar ist:

  • Führen Sie checkbashisms aus darauf, ein Tool aus dem Debian-Projekt, das ein Skript auf „Bashismen“ prüft.

  • Führen Sie es unter posh aus , eine Shell im Debian-Paket-Repository, die absichtlich nur von SUS3 spezifizierte Features implementiert, plus ein paar andere kleinere Features.

  • Führen Sie es unter obosh aus aus dem Schily Tools-Projekt, eine verbesserte Version der Bourne-Shell als Open Source von Sun als Teil von OpenSolaris im Jahr 2005, was es zu einer der einfachsten Möglichkeiten macht, eine Bourne-Shell im Stil von 1979 auf einem modernen Computer zu installieren.

    Die Schily Tools-Distribution enthält auch bosh , eine Shell vom Typ POSIX mit vielen nicht standardmäßigen Funktionen, die jedoch nützlich sein kann, um die Kompatibilität von Shell-Skripten zu testen, die auf allen Shells der POSIX-Familie ausgeführt werden sollen. Es ist tendenziell konservativer in seinem Feature-Set als bash , zsh und die erweiterten Versionen von ksh93 .

    Schily Tools enthält auch eine Shell namens bsh , aber das ist eine historische Kuriosität, die überhaupt kein Gehäuse der Bourne-Familie ist.

  • Lesen Sie das Kapitel Portable Shell Programming im GNU Autoconf-Handbuch. Vielleicht erkennen Sie einige der problematischen Konstrukte, über die es in Ihren Skripten spricht.

Warum sind sie unterschiedlich?

Aus den gleichen Gründen sind alle „Neu &Verbessert!“ Dinge sind anders:

  • Die verbesserte Version konnte nur verbessert werden, indem die Abwärtskompatibilität gebrochen wurde.

  • Jemand hat sich eine andere Art und Weise ausgedacht, wie etwas funktionieren könnte, was ihnen besser gefällt, aber das ist nicht die gleiche Art und Weise, wie die alte funktioniert hat.

  • Jemand hat versucht, einen alten Standard neu zu implementieren, ohne ihn vollständig zu verstehen, also hat er es vermasselt und einen unbeabsichtigten Unterschied geschaffen.

Fußnoten und Randbemerkungen :

  1. Frühe Versionen von BSD Unix waren nur Add-On-Softwaresammlungen für V6 Unix. Da die Bourne-Shell erst in V7 zu AT&T Unix hinzugefügt wurde, hatte BSD technisch gesehen nicht mit der Bourne-Shell begonnen. BSDs Antwort auf die primitive Natur der Thompson-Shell war die C-Shell.

    Trotzdem basierten die ersten Standalone-Versionen von BSD (2.9BSD und 3BSD) auf V7 oder seinem portablen Nachfolger UNIX/32V, also hatten sie es die Bourne-Shell enthalten.

    (Die 2BSD-Reihe wurde zu einer parallelen Abzweigung von BSD für Digitals PDP-Minicomputer, während die 3BSD- und 4BSD-Reihen fortfuhren, neuere Computertypen wie Vaxen- und Unix-Workstations zu nutzen. 2.9BSD war im Wesentlichen die PDP-Version von 4.1cBSD; das waren sie gleichzeitiger und geteilter Code. PDPs verschwanden nicht einfach, als die VAX ankam, also watschelt die 2BSD-Linie immer noch dahin.)

    Man kann mit Sicherheit sagen, dass die Bourne-Shell 1983 überall in der Unix-Welt war. Das ist eine gute Annäherung an „für immer“ in der Computerindustrie. MS-DOS bekam in diesem Jahr ein hierarchisches Dateisystem (aww, wie süß!) und den ersten 24-Bit-Macintosh mit seinem 9-Zoll-B&W-Bildschirm – nicht Graustufen, buchstäblich schwarz und weiß – würde erst Anfang nächsten Jahres herauskommen.

  2. Die Thompson-Schale war nach heutigen Maßstäben ziemlich primitiv. Es war nur eine interaktive Befehlsshell und nicht die Skript-Programmierumgebung, die wir heute erwarten. Es hatte Dinge wie Pipes und E/A-Umleitung, die wir als prototypischen Teil einer „Unix-Shell“ betrachten, sodass wir davon ausgehen, dass die MS-DOS-Befehlsshell sie von Unix erhält.

    Die Bourne-Shell ersetzte auch die PWB-Shell, die der Thompson-Shell wichtige Dinge wie Programmierbarkeit hinzufügte (if , switch und while ) und eine frühe Form von Umgebungsvariablen. Die PWB-Shell ist noch weniger in Erinnerung als die Thompson-Shell, da sie nicht Teil jeder Unix-Version war.

  3. Wenn jemand nicht ist speziell in Bezug auf die Kompatibilität von POSIX und Bourne-Shell gibt es eine ganze Reihe von Dingen, die sie bedeuten könnten.

    Auf der einen Seite könnten sie die Bourne-Shell von 1979 als Basis verwenden. Ein „sh -kompatibles Skript“ in diesem Sinne bedeuten, dass es perfekt auf der echten Bourne-Shell oder einem ihrer Nachfolger und Klone laufen soll:ash , bash , ksh , zsh usw.

    Jemand am anderen Extrem nimmt stattdessen die von POSIX angegebene Shell als Basislinie an. Wir nehmen heutzutage so viele Funktionen der POSIX-Shell als „Standard“, dass wir oft vergessen, dass sie in der Bourne-Shell eigentlich nicht vorhanden waren:eingebaute Arithmetik, Jobsteuerung, Befehlshistorie, Aliase, Befehlszeilenbearbeitung, der $() Form der Befehlsersetzung usw.

  4. Obwohl die Wurzeln der Korn-Shell bis in die frühen 1980er Jahre zurückreichen, hat AT&T sie erst mit System V Release 4 im Jahr 1988 in Unix ausgeliefert. Da so viele kommerzielle Unixe auf SVR4 basieren, wurde hier ksh gesetzt in so ziemlich jedem relevanten kommerziellen Unix seit den späten 1980er Jahren.

    (Ein paar seltsame Unix-Varianten, die auf SVR3 und früher basierten, hielten sich nach der Veröffentlichung von SVR4 am Markt fest, aber sie waren die ersten, die gegen die Wand drängten, als die Revolution kam.)

    1988 ist auch das Jahr, in dem der erste POSIX-Standard mit seiner Korn-Shell-basierten „POSIX-Shell“ herauskam. Später, im Jahr 1993, kam eine verbesserte Version der Korn-Shell heraus. Da POSIX das Original effektiv an Ort und Stelle genagelt hat, ksh in zwei Hauptversionen aufgeteilt:ksh88 und ksh93 , benannt nach den Jahren ihrer Trennung.

    ksh88 ist nicht vollständig POSIX-kompatibel, obwohl die Unterschiede gering sind, sodass einige Versionen des ksh88 Shell wurden gepatcht, um POSIX-kompatibel zu sein. (Dies aus einem interessanten Interview auf Slashdot mit Dr. David G. Korn. Ja, der Typ, der die Shell geschrieben hat.)

    ksh93 ist eine voll kompatible Obermenge der POSIX-Shell. Entwicklung auf ksh93 ist sporadisch aufgetreten, seit das primäre Quell-Repository von AT&T zu GitHub verschoben wurde, wobei die neueste Version etwa 3 Jahre alt ist, während ich dies schreibe, ksh93v. (Der Basisname des Projekts bleibt ksh93 mit hinzugefügten Suffixen, um Release-Versionen nach 1993 zu kennzeichnen.)

    Systeme, die eine Korn-Shell getrennt von der POSIX-Shell enthalten, stellen sie normalerweise als /bin/ksh zur Verfügung , obwohl es sich manchmal woanders versteckt.

    Wenn wir über ksh sprechen oder Korn-Shell namentlich sprechen wir von ksh93 Merkmale, die es von seinen abwärtskompatiblen Bourne- und POSIX-Shell-Subsets unterscheiden. Auf den reinen ksh88 stößt man selten heute.

  5. AT&T hielt den Quellcode der Korn-Shell bis März 2000 proprietär. Zu diesem Zeitpunkt war die Verbindung von Linux mit GNU Bash sehr stark. Bash und ksh93 jeder hat Vorteile gegenüber dem anderen, aber an diesem Punkt hält die Trägheit Linux fest mit Bash verbunden.

    Warum die frühen Linux-Anbieter am häufigsten GNU Bash gegenüber pdksh wählen , was war zu der Zeit, als Linux anfing, verfügbar war, schätze ich, weil so viel vom restlichen Userland auch aus dem GNU-Projekt stammte. Bash ist auch etwas fortgeschrittener als pdksh , da sich die Bash-Entwickler nicht darauf beschränken, Funktionen der Korn-Shell zu kopieren.

    Arbeite an pdksh hörte etwa zu der Zeit auf, als AT&T den Quellcode für die echte Korn-Shell veröffentlichte. Es gibt jedoch zwei Hauptzweige, die noch gepflegt werden:der OpenBSD pdksh und die MirBSD-Korn-Shell, mksh .

    Ich finde es interessant, dass mksh ist die einzige derzeit für Cygwin gepackte Korn-Shell-Implementierung.

  6. GNU Bash geht in vielerlei Hinsicht über POSIX hinaus, aber Sie können es bitten, in einem reineren POSIX-Modus zu laufen.

  7. csh /tcsh war in den frühen 1990er Jahren normalerweise die interaktive Standard-Shell auf BSD-Unixen.

    Da es sich um eine BSD-Variante handelte, waren frühe Versionen von Mac OS X bis Mac OS X 10.2 „Jaguar“ so. OS X hat die Standard-Shell von tcsh geändert Bash in OS X 10.3 „Panther“. Diese Änderung wirkte sich nicht auf Systeme aus, die von 10.2 oder früher aktualisiert wurden. Die bestehenden Benutzer auf diesen konvertierten Systemen behielten ihren tcsh Schale.

    FreeBSD behauptet, immer noch tcsh zu verwenden als Standard-Shell, aber auf der FreeBSD 10-VM, die ich hier habe, scheint die Standard-Shell eine der POSIX-kompatiblen Almquist-Shell-Varianten zu sein. Dies gilt auch für NetBSD.

    OpenBSD verwendet einen Fork von pdksh stattdessen als Standard-Shell.

    Die höhere Popularität von Linux und OS X lässt einige Leute wünschen, dass FreeBSD auch auf Bash umsteigen würde, aber sie werden dies aus philosophischen Gründen in absehbarer Zeit nicht tun. Es ist einfach zu wechseln, wenn Sie das stört.

  8. Es ist selten, ein System mit einer wirklich einfachen Bourne-Shell als /bin/sh zu finden heutzutage. Sie müssen sich die Mühe machen, etwas zu finden, das ihm für Kompatibilitätstests ausreichend nahe kommt.

    Mir ist nur eine Möglichkeit bekannt, eine echte Vintage-Bourne-Shell von 1979 auf einem modernen Computer auszuführen:Verwenden Sie die Ancient Unix V7-Disk-Images mit dem SIMH PDP-11-Simulator aus dem Computer History Simulation Project. SIMH läuft auf so ziemlich jedem modernen Computer, nicht nur auf Unix-ähnlichen. SIMH läuft sogar auf Android und auf iOS.

    Mit OpenSolaris hat Sun erstmals die SVR4-Version der Bourne-Shell veröffentlicht. Davor war der Quellcode für die Post-V7-Versionen der Bourne-Shell nur für Benutzer mit einer Unix-Quellcodelizenz verfügbar.

    Dieser Code ist jetzt separat vom Rest des nicht mehr existierenden OpenSolaris-Projekts aus verschiedenen Quellen verfügbar.

    Die direkteste Quelle ist das Shell-Projekt Heirloom Bourne. Diese wurde kurz nach der ursprünglichen Veröffentlichung von OpenSolaris im Jahr 2005 verfügbar. In den nächsten Monaten wurden einige Portabilitäts- und Fehlerbehebungsarbeiten durchgeführt, aber dann wurde die Entwicklung des Projekts gestoppt.

    Jörg Schilling hat eine bessere Arbeit geleistet, eine Version dieses Codes als obosh zu pflegen in seinem Schily Tools Paket. Siehe oben für mehr dazu.

    Denken Sie daran, dass diese Shells, die von der Quellcode-Veröffentlichung von 2005 abgeleitet wurden, Unterstützung für Multibyte-Zeichensätze, Jobsteuerung, Shell-Funktionen und andere Funktionen enthalten, die in der ursprünglichen Bourne-Shell von 1979 nicht vorhanden waren.

    Eine Möglichkeit, festzustellen, ob Sie sich auf einer originalen Bourne-Shell befinden, besteht darin, zu prüfen, ob sie ein undokumentiertes Feature unterstützt, das hinzugefügt wurde, um den Übergang von der Thompson-Shell zu erleichtern:^ als Alias ​​für | . Das heißt, ein Befehl wie ls ^ more gibt auf einer Korn- oder POSIX-Shell einen Fehler aus, verhält sich aber wie ls | more auf einer echten Bourne-Shell.

  9. Gelegentlich begegnen Sie einem fish , scsh oder rc/es Anhänger, aber sie sind noch seltener als C-Shell-Fans.

    Der rc Familie von Shells wird auf Unix/Linux-Systemen nicht häufig verwendet, aber die Familie ist historisch wichtig, weshalb sie sich einen Platz im obigen Diagramm verdient hat. rc ist die Standard-Shell des Betriebssystems Plan 9 von Bell Labs, eine Art Nachfolger der 10. Ausgabe von Unix, das als Teil der kontinuierlichen Forschung von Bell Labs zum Betriebssystemdesign entwickelt wurde. Es ist auf Programmierebene sowohl mit Bourne als auch mit der C-Shell inkompatibel; Da ist wahrscheinlich eine Lektion drin.

    Die aktivste Variante von rc scheint das von Toby Goodwin gepflegte zu sein, das auf Unix rc basiert Klon von Byron Rakitzis.

Verwandte:Datei aus Docker-Image extrahieren?
Linux
  1. Was bedeutet „–“ (Doppelstrich)?

  2. Was bedeutet „:-“ in einem Shell-Skript?

  3. Was bedeutet kaufmännisches Und am Ende einer Shell-Skriptzeile?

  4. Was bedeutet in der Ausgabe von Ps?

  5. Was bedeutet „rm ist gehasht“?

Was bedeutet chmod 777

Was bedeutet „chown Root.root $file“?

Keine X11-DISPLAY-Variable - was bedeutet das?

Was bedeutet diese Warnung?

Was bedeutet #define X X?

Was bedeutet kill-3?