Unix-Philosophie

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche

Die Unix-Philosophie ist eine Menge von Regeln und Herangehensweisen bei der Software-Entwicklung, die auf den Erfahrungen der führenden Unix-Programmierer basieren.

McIlroy: A Quarter Century of Unix[Bearbeiten]

Douglas McIlroy, der Erfinder der Unix-Pipes, fasste die Philosophie folgendermaßen zusammen:

  • Schreibe Computerprogramme so, dass sie nur eine Aufgabe erledigen und diese gut machen.
  • Schreibe Programme so, dass sie zusammenarbeiten.
  • Schreibe Programme so, dass sie Textströme verarbeiten, denn das ist eine universelle Schnittstelle.

Gewöhnlich wird das verkürzt zu: „Mache nur eine Sache und mache sie gut.

Von diesen drei Lehrsätzen sind vor allem die ersten beiden nicht auf Unix beschränkt, jedoch betonen Unix-Programmierer alle drei Lehrsätze stärker als andere Programmierer.

Pike: Notes on Programming in C[Bearbeiten]

Rob Pike schlägt in dem Text Notes on Programming in C die folgenden Regeln als Grundsätze des Programmierens vor, jedoch kann man sie genauso als Kerngedanken der Unix-Philosophie sehen:

  • Regel 1: Man kann nicht sagen, welcher Programmteil den Hauptteil der Leistung fressen wird. Da Engpässe oft an überraschenden Stellen auftauchen, soll man nichts zur Erhöhung der Geschwindigkeit einbauen, bevor man gezeigt hat, wo der Engpass sitzt.
  • Regel 2: Miss die Programmlaufzeit. Feile erst an der Geschwindigkeit, wenn du sie gemessen hast, und selbst dann erst, wenn der betrachtete Teil einen dominierenden Anteil der Rechenzeit frisst.
  • Regel 3: Ausgefallene Algorithmen sind langsam, wenn die Eingabedatenmenge n [siehe Komplexitätstheorie] klein ist, und das ist der Normalfall. Ausgefallene Algorithmen haben große Fixkosten. Solange man nicht weiß, dass n häufig große Werte annehmen wird, soll man auf ausgefallene Algorithmen verzichten. (Und selbst wenn n groß wird, gilt zuerst Regel 2.)
  • Regel 4: Ausgefallene Algorithmen sind fehlerhafter als einfache, und sie sind viel schwieriger zu implementieren. Benutze sowohl einfache Algorithmen als auch einfache Datenstrukturen.
  • Regel 5: Daten sind wichtiger. Wenn du die richtigen Datenstrukturen gewählt hast und alles gut gestaltet ist, werden sich die Algorithmen fast immer von alleine ergeben. Datenstrukturen sind das zentrale Thema des Programmierens, nicht Algorithmen.
  • Regel 6: Es gibt keine Regel 6.

Die Regeln 1 und 2 wiederholen den berühmten Grundsatz von Tony Hoare: „Zu frühe Optimierung ist die Wurzel allen Übels.Ken Thompson formulierte die Regeln 3 und 4 als „Verwende im Zweifelsfall rohe Gewalt“; diese Regeln sind Beispiele für das KISS-Prinzip. Die Regel 5 stammt von Fred Brooks, der sie im Buch The Mythical Man-Month erwähnt hat, und wird oft formuliert als „schreibe dummen Code, der schlaue Daten verwendet“. Die Regel 6 ist dem Bruces-Sketch aus Monty Python’s Flying Circus (Folge 22) entlehnt.

Mike Gancarz: The UNIX Philosophy[Bearbeiten]

1994 veröffentlichte Mike Gancarz seine eigenen Erfahrungen mit Unix (er gehörte zu den Entwicklern des X Window System) zusammen mit Gedanken aus Diskussionen mit Kollegen sowie Leuten aus anderen Gebieten, welche ebenfalls auf Unix angewiesen waren, zusammengefasst als The Unix Philosophy. Darin werden neun Hauptforderungen genannt:

  1. Klein ist schön.
  2. Gestalte jedes Programm so, dass es eine Aufgabe gut erledigt.
  3. Erzeuge so bald wie möglich einen funktionierenden Prototyp.
  4. Bevorzuge Portierbarkeit vor Effizienz.
  5. Speichere Daten in einfachen Textdateien.
  6. Verwende die Hebelwirkung der Software zu deinem Vorteil.
  7. Verwende Shell-Skripte, um die Hebelwirkung und die Portierbarkeit zu verbessern.
  8. Vermeide Benutzeroberflächen, die den Benutzer fesseln.
  9. Mache jedes Programm zu einem Filter.

Die folgenden zehn weniger strengen Forderungen werden nicht allgemein als Teil der Unix-Philosophie akzeptiert und führen zum Teil auch zu heftigen Debatten (beispielsweise beim Thema monolithischer Kernel vs. Microkernel):

  1. Lass den Benutzer die Umgebung nach seinen Bedürfnissen festlegen.
  2. Mache Betriebssystemkerne klein und leichtgewichtig.
  3. Benutze Kleinschreibung und halte Befehlsnamen kurz.
  4. Verschwende keine Bäume.
  5. Schweigen ist Gold.
  6. Denke parallel.
  7. Die Summe der Teile ist mehr als das Ganze.
  8. Suche die 90/10-Lösung.
  9. Schlechter ist besser.
  10. Denke hierarchisch.

Schlechter ist besser[Bearbeiten]

Richard P. Gabriel behauptet, ein grundlegender Vorteil von Unix komme von einer Designphilosophie, die er als schlechter ist besser bezeichnet. Nach dieser Philosophie ist die Einfachheit sowohl der Benutzerschnittstelle als auch der Umsetzung im Programm viel wichtiger als jede andere Eigenschaft des Systems – inklusive Eigenschaften wie Fehlerfreiheit, Konsistenz und Vollständigkeit. Gabriel argumentiert, dass diese Vorgehensweise grundlegende Vorteile bei der Weiterentwicklung der Software bietet, allerdings zweifelt er auch an der Qualität bei so mancher Umsetzung dieser Vorgehensweise.

Beispielsweise besaßen die ersten Unix-Systeme einen rein monolithischen Kernel; Benutzerprozesse, die Kernel-Funktionsaufrufe durchführten, verwendeten für diese den User-Stack. Wenn nun ein Signal an einen Prozess geschickt werden soll, während dieser durch einen länger andauernden Kernel-Funktionsaufruf blockiert ist, kann der Signal-Handler nicht ausgeführt werden – denn es befinden sich möglicherweise kritische Daten für den Kernel auf dem Stack. Was soll getan werden? Eine Möglichkeit wäre, mit dem Signal zu warten, bis der Kernel-Aufruf beendet ist – das kann jedoch sehr lange dauern, manchmal zu lange. Eine weitere Möglichkeit wäre, den Kernel-Aufruf zwischenzuspeichern, um ihn später fortsetzen zu können, vorausgesetzt, beim Signal-Handler läuft alles glatt.

In solchen Fällen bevorzugten Ken Thompson und Dennis Ritchie Einfachheit vor Perfektion. Wenn ein solcher Fall eintritt, beendet der Kernel den Funktionsaufruf mit einer Fehlermeldung, die besagt, dass der Funktionsaufruf nicht ausgeführt wurde (dies ist der Interrupted System Call, mit der Fehlernummer 4 = EINTR; diese Unterbrechung kam natürlich vom Signal-Handler). Das kommt nur bei einer Handvoll lang andauernder Systemaufrufe wie z.B. read(), write(), open(), select() usw vor. Diese Vorgehensweise hat den Vorteil, dass sie das I/O-System wesentlich einfacher macht (da Sonderfälle nicht berücksichtigt werden müssen). Die meisten Programme stört das nicht, weil sie sowieso keine Signale verwenden bzw. sich bei einem SIGINT beenden. Die paar wenigen Programme, die Signale verwenden, können auf dieses Problem reagieren, indem sie die Kernel-Funktionsaufrufe mit einem Wrapper umgeben, der bei einem aufgetretenem EINTR den Aufruf gleich noch einmal wiederholt. Damit ist das Problem auf eine einfache Art gelöst.

Aus diesen Gründen war Unix in seiner Anfangszeit das Betriebssystem, das am häufigsten abstürzte (mehrmals pro Tag), allerdings auch den schnellsten Neustart hatte. Wegen seiner Einfachheit wurde innerhalb von zehn Jahren aus Unix das stabilste System, das mit fehlerfreien Laufzeiten im Bereich von Monaten und Jahren statt Stunden aufwarten konnte.

Raymond: The Art of Unix Programming[Bearbeiten]

Eric S. Raymond fasst in seinem Buch The Art of Unix Programming die Unix-Philosophie mit der allseits bekannten Ingenieursweisheit Keep it Simple, Stupid (KISS) zusammen. Anschließend beschreibt er, wie diese Grundhaltung seiner Meinung nach in der Praxis der Unix-Kultur umgesetzt wird (wobei in der Praxis natürlich gelegentlich sehr deutlich gegen diese Regeln verstoßen wird):

  • Regel der Modularität: Schreibe einfache Bestandteile, die durch saubere Schnittstellen verbunden werden.
  • Regel der Klarheit: Klarheit ist besser als Gerissenheit.
  • Regel des Zusammenbaus: Entwirf Programme so, dass sie mit anderen Programmen verknüpft werden können.
  • Regel der Trennung: Trenne den Grundgedanken von der Umsetzung, trenne die Schnittstellen von der Verarbeitungslogik.
  • Regel der Einfachheit: Entwirf mit dem Ziel der Einfachheit; füge Komplexität nur hinzu, wenn es unbedingt sein muss.
  • Regel der Sparsamkeit: Schreibe nur dann ein großes Programm, wenn sich klar zeigen lässt, dass es anders nicht geht.
  • Regel der Transparenz: Entwirf mit dem Ziel der Durchschaubarkeit, um die Fehlersuche zu vereinfachen.
  • Regel der Robustheit: Robustheit ist das Kind von Transparenz und Einfachheit.
  • Regel der Darstellung: Stecke das Wissen in die Datenstrukturen, so dass die Programmlogik dumm und robust sein kann.
  • Regel der geringsten Überraschung: Mache beim Entwurf der Schnittstellen immer das Nächstliegende, welches für die wenigsten Überraschungen beim Benutzer sorgt.
  • Regel der Stille: Wenn ein Programm nichts Überraschendes zu sagen hat, soll es schweigen.
  • Regel des Reparierens: Wenn das Programm scheitert, soll es das lautstark und so früh wie möglich tun.
  • Regel der Wirtschaftlichkeit: Die Arbeitszeit von Programmierern ist teuer; spare sie auf Kosten der Rechenzeit.
  • Regel der Code-Generierung: Vermeide Handarbeit; schreibe Programme, die Programme schreiben, falls möglich.
  • Regel der Optimierung: Erstelle Prototypen, bevor du dich an den Feinschliff machst. Mache es lauffähig, bevor du es optimierst.
  • Regel der Vielseitigkeit: Misstraue allen Ansprüchen auf „den einzig wahren Weg“.
  • Regel der Erweiterbarkeit: Entwirf für die Zukunft, denn sie wird schneller kommen als du denkst.

Viele dieser Normen werden auch außerhalb der Unix-Gemeinde anerkannt – wenn sie nicht zuerst bei Unix verwendet wurden, wurden sie bald übernommen. Trotzdem betrachten Unix-Experten eine Kombination dieser Regeln als die Grundlage des Unix-Stils.

Rolle des Betriebssystems[Bearbeiten]

Obige Aussagen beschreiben, welche Eigenschaften Programme haben, die Unix zu dem machen, was es ist. Ein weiterer Aspekt der Unix-Philosophie betrifft jedoch auch das Betriebssystem selbst: Damit Programme möglichst einfach, klar und modular gehalten werden können, damit sie gut zusammenarbeiten können und damit sie gut portierbar sein können, muss das Betriebssystem die entsprechenden Voraussetzungen in Form von klaren Schnittstellen und hoher Abstraktion schaffen. In der Praxis:

Alles ist eine Datei[Bearbeiten]

Hauptartikel: Everything is a file
  • Der Zugriff sowohl auf lokale Laufwerke wie auch Netzlaufwerke erfolgt über dieselbe Verzeichnisstruktur; es gibt nicht verschiedene Laufwerke, sondern alles sind Verzeichnisse und Dateien in derselben Baumstruktur.
  • Virtuelle Laufwerke können ebenfalls problemlos realisiert werden, denn sie erscheinen ebenfalls nur als Verzeichnis. Jede Image-Datei an jedem Ort kann durch mounten in den Verzeichnisbaum an jeder Stelle eingebunden werden.
  • Auch der Zugriff auf Geräte erfolgt über das Dateisystem. Einem Gerätetreiber wird eine Gerätedatei im Verzeichnis /dev zugeordnet; durch Lesen und Schreiben dieser Datei kann ein Programm mit dem Gerätetreiber kommunizieren.
  • Auf Kernel-Daten kann ebenfalls über die Verzeichnisstruktur zugegriffen werden, und zwar über das Verzeichnis /proc.

Client-Server-Modell[Bearbeiten]

Hauptartikel: Client-Server-Modell

Kommunikation erfolgt grundsätzlich über Netzwerk-Verbindungen. Auch die interne Kommunikation zwischen beispielsweise Client-Programmen und Daemons wird über Netzwerkschnittstellen geführt, so dass die Programmierung einheitlich ist und die Programme auch wahlweise über das Netzwerk verwendet werden können.

Aus diesem Grund gibt es bei Unix nicht für jedes Anwendungsgebiet eine spezialisierte Programmierschnittstelle, sondern auch vergleichsweise exotische Anwendungen werden auf Dateien oder Netzwerkverbindungen abgebildet.

Zitate[Bearbeiten]

  • Unix ist einfach. Es erfordert lediglich ein Genie, um seine Einfachheit zu verstehen.“ – Dennis Ritchie
  • Unix wurde nicht entwickelt, um seine Benutzer daran zu hindern, dumme Dinge zu tun, denn das würde diese auch davon abhalten, schlaue Dinge zu tun.“ – Doug Gwyn
  • Unix sagt niemals ›bitte‹.“ – Rob Pike

Siehe auch[Bearbeiten]

Quellen[Bearbeiten]

Weblinks[Bearbeiten]