Loading AI tools
Menge von Regeln bei der Unix-Programmierung Aus Wikipedia, der freien Enzyklopädie
Die Unix-Philosophie ist eine Menge von Regeln und Herangehensweisen bei der Software, die auf den Erfahrungen der führenden Unix-Programmierer basieren.
Douglas McIlroy, der Erfinder der Unixpipes, fasste die Philosophie folgendermaßen zusammen:
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.
Rob Pike schlägt die folgenden Regeln als Grundsätze des Programmierens vor,[1] jedoch kann man sie genauso als Kerngedanken der Unix-Philosophie sehen:
Die Regeln 1 und 2 wiederholen den berühmten Grundsatz von Donald E. Knuth: „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. Regel 5 stammt von Fred Brooks, der sie im Buch Vom Mythos des Mann-Monats erwähnt hat und wird oft als „Schreibe dummen Code, der schlaue Daten verwendet.“ formuliert. Die Regel 6 ist dem Sketch von Bruces aus Monty Python’s Flying Circus (Folge 22) entlehnt.
1994 veröffentlichte Mike Gancarz (er gehörte zu den Entwicklern des X Window Systems) seine Erfahrungen mit Unix in Form des Buches The Unix Philosophy, das sich auch auf Anekdoten aus Diskussionen mit Kollegen stützt sowie mit Leuten aus anderen Gebieten, die selbst auf Unix angewiesen waren. Darin werden neun Hauptforderungen genannt:
Die folgenden zehn weniger strengen Forderungen werden nicht allgemein als Teil der Unixphilosophie akzeptiert und führten zum Teil auch zu heftigen Debatten (beispielsweise, ob ein monolithischer Kernel oder ein Mikrokernel bevorzugt werden solle):
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 biete, allerdings zweifelt er auch an der Qualität der Programme bei so mancher Umsetzung dieser Vorgehensweise.
Beispielsweise besaßen die ersten Unixsysteme einen rein monolithischen Kernel; Benutzerprozesse, die Kernelfunktionsaufrufe durchführten, verwendeten für diese den Userstack. Wenn nun ein Signal an einen Prozess geschickt werden sollte, während dieser durch einen länger andauernden Kernelfunktionsaufruf blockiert war, konnte der Signalhandler nicht ausgeführt werden – denn es befanden sich möglicherweise kritische Daten für den Kernel auf dem Stack. Was sollte getan werden? Eine Möglichkeit wäre, mit dem Signal zu warten, bis der Kernelaufruf beendet ist – das kann jedoch sehr lange dauern, manchmal zu lange. Eine weitere Möglichkeit wäre, den Kernelaufruf unter der Voraussetzung, dass beim Signalhandler alles glattläuft, zwischenzuspeichern, um ihn später fortsetzen zu können.
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 Signalhandler). 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 Kernelfunktionsaufrufe mit einem Wrapper umgeben, der bei einem aufgetretenen 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.
Eric S. Raymond fasst in seinem Buch The Art of Unix Programming die Unixphilosophie 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 Unixkultur umgesetzt wird (wobei in der Praxis natürlich gelegentlich sehr deutlich gegen diese Regeln verstoßen wird):
Viele dieser Normen werden auch außerhalb der Unix-Gemeinde anerkannt[2] – 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.
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:
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.