6 Grundlagen aus Anwendersicht
6 Grundlagen aus Anwendersicht
6 Grundlagen aus Anwendersicht
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
»Was für eine Philosophie man wähle,<br />
hängt davon ab,<br />
was für ein Mensch man ist.«<br />
– Johann Gottlieb Fichte<br />
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
Im letzten Kapitel haben wir uns <strong>aus</strong>führlich mit dem Kernel und den Aufgaben<br />
eines Betriebssystems wie Linux <strong>aus</strong>einandergesetzt. In diesem Kapitel wollen wir<br />
uns nun mit dem Userland 1 und den <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong> beschäftigen.<br />
Wurden im ersten Kapitel also vorrangig interessante Hintergründe vermittelt und<br />
ein grundlegendes Verständnis für das Betriebssystem als Ganzes geschaffen, so<br />
möchten wir uns im Folgenden so langsam der Praxis zuwenden. Dazu setzen<br />
wir eigentlich nur vor<strong>aus</strong>, dass Sie ein Linux-System, egal welcher Distribution,<br />
zur Hand haben. Vielleicht haben Sie sich im vorhergehenden Teil des Buches<br />
bereits ein System installiert, ansonsten können Sie fürs Erste natürlich auch die<br />
Live-Version von openSUSE oder Fedora von der dem Buch beigefügten DVD-ROM<br />
booten. Beide Systeme sind ohne Installation direkt von der DVD benutzbar und<br />
bieten Ihnen die grafischen Oberflächen KDE (openSUSE) und GNOME (Fedora).<br />
Im Großen und Ganzen werden wir dabei unserer Philosophie treu bleiben und<br />
Linux distributionsunabhängig beschreiben. Wir werden Ihnen nicht nur erklären,<br />
wie man etwas genau macht, sondern Ihnen vor allem das Warum und Wieso sowie<br />
die Zusammenhänge insgesamt erläutern. Trotzdem wollen wir darauf achten, uns<br />
nicht in Belanglosigkeiten und praxisfernen Konzepten zu verlieren, sondern hier<br />
und da auch einmal ein konkretes und vor allem interessantes Beispiel zu bringen.<br />
Von Ihnen verlangen wir eigentlich nur die Bereitschaft, sich auf unseren zugegeben<br />
etwas eigenwilligen Stil einzulassen.<br />
Linux pur!<br />
6.1 Die Unix-Philosophie<br />
Um die <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong> ordentlich verstehen zu können, braucht<br />
man zuerst einmal ein Verständnis für die Philosophie hinter diesem Betriebssys-<br />
1 Als Userland, auchUserspace, bezeichnet man die Systemumgebung <strong>aus</strong> Sicht eines Benutzers.<br />
175
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
tem. Außerdem muss man verstehen, dass Unix und Linux eng zusammenhängen –<br />
wer einen Linux-Rechner administrieren kann, braucht nur eine sehr kurze Einarbeitungszeit,<br />
um andere Unix-Systeme wie Solaris oder BSD zu verstehen. Alle diese<br />
Systeme haben eine Gemeinsamkeit: Für Windows-Anwender wirken sie zunächst<br />
»anders« und »ungewohnt«, vielleicht sogar »umständlich«. Aber die Entwickler haben<br />
sich etwas bei der Konstruktion dieses Systems gedacht, und wir wollen Ihnen<br />
diese Gedanken nun näherbringen.<br />
Von<br />
Programmierern für<br />
Programmierer<br />
Zuerst einmal wurde Unix von Programmierern für Programmierer 2 entwickelt.<br />
Auf einem System können mehrere Benutzer mehrere Programme gleichzeitig nutzen,<br />
zum Beispiel um Software zu entwickeln oder anderweitig zu arbeiten. Die Benutzer<br />
sowie die einzelnen Programme können Daten gemeinsam nutzen sowie diese auf<br />
eine kontrollierte Art und Weise <strong>aus</strong>t<strong>aus</strong>chen. Das Design von Unix setzt dabei<br />
einigermaßen intelligente Benutzer vor<strong>aus</strong>, die in der Regel wissen, was sie tun<br />
– sollte dies aber nicht der Fall sein oder sind böswillige Angreifer am Werk, ist<br />
das System durch die Implementierung von unterschiedlichen Benutzerkonten mit<br />
einem konsistenten Rechtesystem gut vor Manipulationen geschützt.<br />
All diese Ziele unterscheiden sich nun gewaltig von denen eines Einbenutzerbetriebssystems,<br />
das auch Anfängern ermöglichen will, eine Textverarbeitung zu benutzen.<br />
Dort möchte man die Benutzer führen und ein Stück weit auch bevormunden,<br />
da das System meistens besser weiß, was gut für den Anwender ist, als dieser<br />
selber.<br />
6.1.1 Kleine, spezialisierte Programme<br />
Das genaue Gegenteil ist bei Programmierern oder anderweitig erfahrenen Anwendern<br />
der Fall: Sie erwarten von einem System, dass es die ihm gestellten Aufgaben<br />
effizient löst. Das System muss sich nicht um seine Benutzer kümmern, denn diese<br />
wissen in der Regel selbst, was sie wollen und wie sie es erreichen können. Das<br />
System muss dazu flexibel und mächtig sein, was Unix auf dem folgenden Weg zu<br />
erreichen versucht:<br />
Anstatt große und funktionsbeladene Applikationen anzubieten, werden kleine,<br />
spezialisierte Programme bereitgestellt. Jedes Programm sollte idealerweise nur<br />
eine Aufgabe erfüllen, diese aber optimal. Durch vielfältige Kombinationen dieser<br />
»Spezialisten« kann ein Anwender nun flexibel die ihm gestellten Aufgaben<br />
bewältigen.<br />
2 Die Zielgruppe »Programmierer« kann jedoch insgesamt als »professionelle Benutzer« verstanden<br />
werden. In den Anfangstagen der Informatik und damit in den Anfangstagen von<br />
Unix war beides noch identisch.<br />
176
Die Unix-Philosophie 6.1<br />
Außerdem unterstützen alle Programme eine konsistente und redundanzarme Bedienung:<br />
Warum sollte man remove schreiben, wenn rm <strong>aus</strong>sagekräftig genug und<br />
immer noch eindeutig ist? Außerdem sollte sich der Befehl analog zu anderen Befehlen<br />
verhalten: Wenn ls -R * alle Inhalte in einem Verzeichnis rekursiv auflistet,<br />
sollte rm -R * alle diese Dateien rekursiv löschen – und nicht etwa eine Datei namens<br />
* und eine Datei, deren Name <strong>aus</strong> einem Minus, gefolgt von einem großen<br />
»R« besteht.<br />
Wenig Redundanz<br />
Überhaupt wird die textuelle Eingabe über die Shell der Bedienung des Systems<br />
über eine grafische Oberfläche in vielen Fällen vorgezogen. Bei knapp hundert<br />
Anschlägen pro Minute tippt sich so ein rm-Befehl viel schneller als man je<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
zur M<strong>aus</strong> greifen,<br />
den Dateimanager durch Doppelklick starten,<br />
die Dateien her<strong>aus</strong>suchen,<br />
sie mit der M<strong>aus</strong> markieren,<br />
das Kontextmenü durch einen Rechtsklick öffnen,<br />
den Punkt Löschen <strong>aus</strong>wählen<br />
und die ganze Aktion durch das Klicken auf Ja in der Dialogbox bestätigen kann.<br />
Auch kann man in der Shell Befehle einfach kombinieren und häufige oder etwas<br />
komplexere Befehle in ganze Skripts schreiben. Diese Skripts können auch zentral<br />
abgelegt und allen Benutzern eines Systems zur Verfügung gestellt werden. Alternativ<br />
kann man diese Skripts zu bestimmten Zeitpunkten – beispielsweise jeden Tag,<br />
jede Woche, jeden ersten Sonntag im Monat um 3 Uhr oder in genau zwei Stunden<br />
– <strong>aus</strong>führen lassen.<br />
6.1.2 Wenn du nichts zu sagen hast: Halt die Klappe<br />
Ein weiterer wichtiger Punkt der Unix-Philosophie ist das Verhalten sowie indirekt<br />
auch die Bedienung der Programme. Programme unter Unix/Linux verhalten sich<br />
nämlich so, wie ein erfahrener Benutzer es erwarten würde: Sie geben im Erfolgsfall<br />
keine Meldung <strong>aus</strong>, sondern nur im Fehlerfall oder wenn es anderweitig Ergebnisse<br />
zu präsentieren gibt. Ein »alles okay« am Ende ist schlicht unnötig und redundant.<br />
Außerdem werden Programme zu einem großen Teil nur über Parameter mit Eingaben<br />
gefüttert: Man startet zum Beispiel einen Texteditor mit der zu bearbeitenden<br />
Datei als Argument, anstatt vom Editor nach dem Start nach der Datei gefragt zu<br />
werden. Für Neulinge ist dies zum Teil recht frustrierend, da man oft Befehle tippt,<br />
die dann keine Ausgabe erzeugen – aber gerade dann ist ja alles in Ordnung.<br />
Parameter statt<br />
Nachfragen<br />
177
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
Diese Prinzipien sind jedoch vor allem in der Shell anzutreffen. Unter grafischen<br />
Oberflächen sind die eben genannten Prinzipien nur schwer zu realisieren und oft<br />
auch nicht sinnvoll.<br />
6.1.3 Die Shell<br />
Ja, die Shell – viel wird von Neulingen über diese »anachronistische« Eingabeaufforderung<br />
geschimpft. Erfahrene Unix-Anwender möchten ihre Shell jedoch nicht<br />
missen und empfinden in der Regel umgekehrt ein System, das sie zur M<strong>aus</strong>benutzung<br />
zwingt, alsZumutung.<br />
Grafik unter<br />
Unix/Linux<br />
Natürlich gibt es auch unter Unix und Linux eine komplette und funktionsreiche<br />
grafische Oberfläche: das X-Window-System. Viele professionelle Unix-Anwender<br />
nutzen diese Oberfläche nur, um viele grafische Terminals und damit viele Shells<br />
gleichzeitig im Blick zu haben. Außerdem bietet zum Beispiel das populäre KDE<br />
als grafische Oberfläche eine nahezu komplette Bedienung über Tastenkürzel und<br />
Shortcuts an. So muss man nicht einmal die Hand von der Tastatur nehmen, wenn<br />
man zu einem anderen Bildschirm 3 oder einer anderen grafischen Shell wechseln<br />
will.<br />
Aber natürlich gibt es auch Anwendungen, die sich in der Shell nur schlecht realisieren<br />
lassen. Ein populäres Beispiel dafür ist das Surfen im Web – es gibt zwar<br />
Webbrowser für eine Textoberfläche, aber eine wirkliche Alternative zu den grafischen<br />
Varianten sind sie nicht.<br />
6.1.4 Administration<br />
Ein weiterer wichtiger Bestandteil der Unix-Philosophie ist die Administration des<br />
Systems. Von vielen wird genau dies als Nachteil gesehen: Man beklagt sich, dass<br />
man bei Linux »basteln« muss, um zu einer vernünftigen Lösung zu kommen. Man<br />
beklagt den fehlenden Hardware-Support für die allerneueste Grafikkarte und dieses<br />
oder jenes nicht unterstützte exotische Feature bei einem neuen PC.<br />
Bastellösungen<br />
Diese Klagen beruhen auf einem Missverständnis. Ja, Unix (und damit auch Linux)<br />
lässt sich bis ins letzte Detail konfigurieren und personalisieren. Schließlich handelt<br />
es sich dabei um ein System für professionelle Anwender und weniger für absolute<br />
Computerneulinge. Und Profis können und wollen sich – zumindest in einem gewissen<br />
Rahmen – mit ihrem System <strong>aus</strong>einandersetzen. Außerdem zieht das Argument<br />
der Bastelei inzwischen nicht mehr wirklich, da heute eine frische Installation einer<br />
3 X11 unterstützt das Konzept der virtuellen Bildschirme, auf denen man jeweils andere Fenster<br />
geöffnet und sogar unterschiedliche Hintergrundbilder aktiviert haben kann. Der Benutzer<br />
kann nun leicht von einem Bildschirm zum anderen wechseln und so die Arbeit mit vielen<br />
Fenstern besser meistern.<br />
178
Die Unix-Philosophie 6.1<br />
gängigen Linux-Distribution weit<strong>aus</strong> weniger Nacharbeit per Hand erfordert als<br />
ein frisches Windows – schließlich ist alle wichtige Software schon installiert und<br />
sinnvoll konfiguriert.<br />
Aber natürlich ist die Welt nicht perfekt. Alle gängigen Fertig-PCs werden mit<br />
Windows <strong>aus</strong>geliefert, da die meisten Hersteller und Händler besondere Verträge<br />
mit Microsoft geschlossen haben. Dass der Kunde dann für Windows bis zu mehrere<br />
hundert Euro bezahlt, auch wenn er diese Software nicht wünscht, sei einmal<br />
dahingestellt. Auf jeden Fall erfordert ein neuer PC mit Windows nicht allzu viel<br />
Handarbeit – das System ist schließlich schon installiert.<br />
Der Schein trügt<br />
Ein neuer PC mit Linux dagegen muss (bis auf wenige Ausnahmen) erst einmal<br />
installiert werden. Ein weiteres Problem von Linux liegt in der mangelhaften Hardwareunterstützung,<br />
die zugegeben an einigen wenigen Stellen immer noch Bastelarbeit<br />
erfordert. Aber seien wir ehrlich: Wer ist für die Bereitstellung korrekter,<br />
funktionsfähiger Treiber zuständig? Freie, unbezahlte Programmierer, die Linux in<br />
ihrer Freizeit weiterentwickeln, oder nicht doch die Hardwarehersteller selbst, die<br />
im Übrigen auch die Windows-Treiber samt aller einfachen Installationsroutinen<br />
zur Verfügung stellen? An diesem Punkt bewegen wir uns leider argumentativ im<br />
Kreis: Denn solange sich die mehrheitlich professionellen Linux/Unix-Anwender<br />
noch mit halbfertigen Bastellösungen auch seitens der Hardwarehersteller zufriedengeben,<br />
wird sich an dieser Situation so schnell nichts ändern.<br />
Fakt ist und bleibt jedoch die Eigenschaft von Linux, dass es sich sehr gut administrieren<br />
und anpassen lässt. Im Moment versucht man hier einen dualen Ansatz: Der<br />
Anwender soll ein System möglichst benutzerfreundlich und einfach installieren<br />
und bedienen können, aber trotzdem weiterhin die gewohnten mächtigen Möglichkeiten<br />
zur Personalisierung haben. Dieses Ziel ist zwar vielleicht noch nicht in<br />
vollem Umfang erreicht, aber man ist bereits auf einem guten Weg.<br />
6.1.5 Netzwerktransparenz<br />
Ein weiterer wichtiger Ansatz der Unix-Philosophie ist die Netzwerktransparenz. Bei<br />
einem durchdachten und konsistenten Mehrbenutzer- und Mehrprogrammkonzept<br />
hat man natürlich auch mit mehreren Rechnern keine Probleme. Die Netzwerktransparenz<br />
spiegelt sich schon in einem in Unix allgegenwärtigen Modell wider: dem<br />
Modell von Dienstnehmer (engl. client) und Dienstgeber (engl. server).<br />
Bei diesem Prinzip der Systemarchitektur nutzt ein Client – meist ein direkt vom Benutzer<br />
gesteuertes Programm – die Dienste eines Servers. Ob dieser Server nun ein<br />
entfernter Rechner mit spezieller Software oder ein lokal im Hintergrund ablaufendes<br />
Programm ist, kann transparent geändert werden. Einige interessante Beispiele<br />
für die Netzwerktransparenz von Unix/Linux wollen wir im Folgenden aufzählen:<br />
Lokalerodernetzwerkbasierter<br />
Dienst?<br />
179
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
<br />
X11 – die grafische Oberfläche<br />
Die grafische Oberfläche von Unix ist auch netzwerktransparent. Man unterscheidet<br />
hier zwischen dem X-Server, der die Darstellung auf dem Client-PC<br />
des Benutzers vornimmt, und den vom Benutzer gestarteten X-Clients, alsoProgrammen,<br />
die eine grafische Oberfläche benötigen. Auf welchem Rechner beziehungsweise<br />
Server diese Clients nun <strong>aus</strong>geführt werden, ist von der Darstellung<br />
durch den X-Server unabhängig – das X-Protokoll trennt die Ausführung und die<br />
Darstellung von grafischen Anwendungen.<br />
Der syslogd<br />
Dateien im<br />
Netzwerk<br />
<br />
<br />
Ein sehr wichtiges, aber leider sehr oft vernachlässigtes Prinzip bei der Entwicklung<br />
sauberer Systeme ist die Orthogonalität: Halte alle Dinge <strong>aus</strong>einander, die<br />
nicht in einem unmittelbaren Zusammenhang stehen.<br />
In unserem Beispiel sind die beiden Aspekte der Ausführung und Darstellung<br />
eines grafischen Programms sauber durch die Trennung von X-Client und X-Server<br />
modelliert.<br />
Der Logging-Dienst<br />
Unter Unix wird sehr viel protokolliert, wobei das Management der Protokoll-<br />
beziehungsweise Logdateien von einem bestimmten Dienst, dem syslogd,<br />
übernommen wird. Die Anwendungen können nun über bestimmte Aufrufe<br />
mit diesem Dienst kommunizieren, der dann die Meldungen in die Dateien<br />
schreibt. Mit wenigen Änderungen an der Systemkonfiguration ist es möglich,<br />
die Anwendungen nicht mehr den lokal laufenden syslogd nutzen zu lassen,<br />
sondern einen auf einem fremden Rechner installierten syslogd.<br />
Die Eigenschaft, mit steigenden Anforderungen mitwachsen zu können, nennt<br />
man Skalierbarkeit.<br />
NFS<br />
Über das virtuelle Dateisystem (VFS) kann man unter Unix, unabhängig vom<br />
darunterliegenden Dateisystem, auf Dateien und Verzeichnisse immer auf die<br />
gleiche Art und Weise zugreifen. Der Benutzer merkt nicht, ob er gerade auf<br />
einer CD-ROM oder einer lokalen Festplatte arbeitet. Dieses Konzept lässt sich<br />
auch auf das Netzwerk <strong>aus</strong>dehnen, bei dem zum Beispiel der für Unix typische<br />
NFS-Dienst ganze Verzeichnisbäume von einem Rechner exportieren und<br />
anderen Systemen im Netzwerk zur Verfügung stellen kann. Die exportierten<br />
Verzeichnisse können von anderen Rechnern schließlich regulär gemountet und<br />
wie lokale Medien benutzt werden – für den Benutzer macht es keinen Unterschied,<br />
dass die Dateien nicht lokal, sondern auf einem anderen Rechner<br />
gespeichert sind.<br />
Diese Liste könnte man fast endlos fortsetzen. Um das Dienstgeber-Konzept zu unterstützen,<br />
bietet Unix spezielle Prozesse an: die Hintergrundprozesse.<br />
180
Der erste Kontakt mit dem System 6.2<br />
Ein Hintergrundprozess ist ein Prozess, der ohne Interaktion mit dem Benutzer seine Arbeit<br />
im Hintergrund verrichtet. Somit benötigt ein solcher Prozess keinen Zugang zur Tastatur<br />
oder direkt zum Bildschirm.<br />
Ein weiteres Prinzip, das zur Netzwerktransparenz führen kann, ist das Spooling. 4<br />
Beim Spooling verwaltet ein Dienst eine Ressource und stellt diese anderen Programmen<br />
über eine bestimmte Schnittstelle zur Verfügung. Ein typisches Beispiel<br />
für Spooling ist die Verwaltung des Druckers: Ein Dienst hat exklusiven Zugriff<br />
auf das Gerät, und druckende Programme greifen nicht direkt auf den Drucker<br />
zu, sondern legen die zu druckenden Dateien einfach in eine Warteschlange. Das<br />
hat den Vorteil, dass zwei gleichzeitig druckende Programme keine Mischung ihrer<br />
Ausdrucke auf dem Papier erzeugen, sondern Druckaufträge nacheinander bearbeitet<br />
werden. Auch die Verwaltung der Logdateien als bestimmte Systemressourcen<br />
durch den syslogd ist eine Art von Spooling. Schließlich können wir nun den<br />
Kreis zur Netzwerktransparenz schließen und anmerken, dass ein solcher Dienst im<br />
Prinzip auf jedem System im Netzwerk <strong>aus</strong>geführt werden kann. 5<br />
Spooling und<br />
das Netzwerk<br />
So viel also erst einmal zur Unix-Philosophie, der sich Linux ebenso wie BSD als<br />
Unix-Derivate selbstverständlich anschließen. Vielleicht haben Ihnen diese Themen<br />
schon etwas Lust auf mehr gemacht; auf jeden Fall werden wir später im Buch alles<br />
näher erläutern. Im Folgenden kommen wir nun endlich zum eigentlichen Thema<br />
des Kapitels: zu einer kurzen Einführung in Linux und BSD.<br />
6.2 Der erste Kontakt mit dem System<br />
In diesem Abschnitt beschäftigen wir uns mit dem ersten Kontakt mit einem Linux-System.<br />
Dieser »erste Kontakt« kann natürlich nicht jeden Aspekt der Kontaktaufnahme<br />
mit dem System umfassend behandeln, daher werden wir später noch<br />
<strong>aus</strong>führlich auf einzelne Punkte eingehen. Der folgende kurze Einstieg schafft jedoch<br />
eine gute Basis für spätere Kapitel.<br />
6.2.1 Booten<br />
Beginnen wir mit dem Start des Systems. Egal, ob bei einer Installation auf Festplatte<br />
oder beim Laden einer Live-Distribution wie Knoppix – das Geschehen ist<br />
eigentlich immer gleich. Im BIOS wird festgelegt, auf welchen Medien in welcher<br />
Reihenfolge nach einem zu bootenden Betriebssystem gesucht werden soll. Dabei<br />
4 Ursprünglich wurde Spooling zum Vermeiden von Ressourcenkonflikten konzipiert.<br />
5 Und tatsächlich gibt es zum Beispiel mit CUPS einen sehr populären netzwerkbasierten<br />
Druckdienst.<br />
181
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
kann mittlerweile sogar von exotischen Geräten wie USB-Sticks gestartet werden,<br />
wobei die meisten Anwender doch lieber bei CD/DVD-Laufwerken und Festplatten<br />
bleiben.<br />
Die ersten Wird nun auf einem der im BIOS angegebenen Bootlaufwerke ein zu startendes<br />
512 Byte Betriebssystem gefunden, wird dieses auch geladen. Auf allen bootfähigen Medien<br />
wird nämlich nach einem gültigen MBR (Master Boot Record) gesucht.Diesistzum<br />
Beispiel bei einer Festplatte immer der erste Sektor (= 512 Bytes) der Festplatte. Er<br />
enthält dabei folgende Informationen:<br />
Bootfähige Medien<br />
erkennen<br />
<br />
<br />
<br />
Bootloader<br />
Der Bootloader besteht <strong>aus</strong> Code zum Laden eines Betriebssystems oder <strong>aus</strong><br />
weiteren Bootloader-Codes. Damit von einem Medium gebootet werden kann,<br />
muss dieser Code gültig sein und ein Betriebssystem laden können.<br />
Partitionstabelle<br />
Die Partitionstabelle gibt an, welche Partitionen wo auf dem Medium vorhanden<br />
sind. Die Partitionstabelle besteht <strong>aus</strong> vier Einträgen zu je 16 Byte und ist damit<br />
insgesamt 64 Byte groß. Sie liegt relativ nah am Ende des Bootsektors bei Byte<br />
446.<br />
Magic Number<br />
Die fehlenden 2 Byte 6 bis zum Ende des Sektors werden nun mit einem Wert<br />
gefällt, anhand dessen das BIOS entscheiden kann, ob es sich um ein bootbares<br />
Medium handelt oder nicht: Ist der Wert 0x55aa, so kann der Code am Anfang<br />
des MBR geladen werden. Ändert man diesen Wert, wird das Medium nicht als<br />
bootfähig erkannt.<br />
Unter Linux können Sie sich den MBR mit folgenden Befehlen ansehen, wobei das<br />
Gerät /dev/sda 7 die erste Festplatte im System bezeichnet, 8 von dem in unserem<br />
Beispiel der MBR gezogen werden soll:<br />
# dd if=/dev/sda of=mbr.img count=1 bs=512<br />
# od -x mbr.img<br />
Listing 6.1 Extrahieren und Betrachten des MBR<br />
Sehen wir uns den Bootvorgang weiter an: Hat man Linux auf seinem System<br />
installiert, so wird mit ziemlicher Sicherheit ein Bootloader wie GRUB geladen. Mit<br />
6 Die Partitionstabelle beginnt bei Byte 446 und ist 64 Byte lang – das ergibt 510 von 512 im<br />
MBR zur Verfügung stehenden Bytes.<br />
7 Entsprechend /dev/hda bei älteren Distributionen, die noch nicht die libata verwenden.<br />
8 Die Gerätenamen sind einer der zahlreichen kleinen Unterschiede zwischen den einzelnen<br />
Unix-Derivaten wie Linux und BSD.<br />
182
Der erste Kontakt mit dem System 6.2<br />
diesem kann man zwischen allen auf diesem Medium installierten Betriebssystemen<br />
das zu startende <strong>aus</strong>wählen.<br />
Als Nächstes wird der Kernel geladen, der das System schließlich allmählich initialisiert<br />
und mit init auch den ersten Prozess des Userlands explizit startet. Dieser<br />
Prozess übernimmt das eigentliche Starten des Systems, indem dafür vorgesehene<br />
Konfigurationsdateien <strong>aus</strong>gelesen und entsprechende Dienste im Hintergrund<br />
gestartet werden.<br />
Der erste<br />
Prozess: init<br />
Dabei werden von init verschiedene Systemkonfigurationen, sogenannte Runlevel,<br />
unterschieden. Je nach Runlevel werden unterschiedliche Dienste gestartet. So gibt<br />
es zum Beispiel bei den meisten Systemen einen Runlevel mit grafischer Oberfläche<br />
und einen ohne. Auch gibt es bestimmte Runlevel zum Herunterfahren (Level 0)<br />
und Neustarten (Level 6) des Systems.<br />
6.2.2 Login<br />
Auch die Login-Dienste der Textoberfläche – realisiert durch das Programm<br />
(m)getty – werden von init gestartet. Je nach Runlevel kann aber auch ein<br />
grafischer Login-Dienst wie GDM oder KDM gestartet sein. In jedem Fall wird der<br />
Nutzer aufgefordert, sich mit einem Usernamen und einem Passwort einzuloggen,<br />
damit er am System arbeiten kann.<br />
Das Login ist dabei wieder ein typisches Beispiel für die Netzwerktransparenz:<br />
Normalerweise wird bei der Anmeldung eines Benutzers überprüft, ob sein Benutzername<br />
in der Datei /etc/passwd verzeichnet ist und mit seinem Passwort in<br />
der Datei /etc/shadow unter Linux beziehungsweise der Datei /etc/master.passwd<br />
unter BSD übereinstimmt. Setzt man im Netzwerk jedoch Dienste wie NIS/NIS+<br />
oder LDAP ein, kann man ein Unix-System überreden, die Benutzerinformationen<br />
von einem solchen zentralen Server zu laden – der Anwender selbst merkt davon<br />
nichts. Verbindet man dieses Feature noch geschickt mit dem Einsatz von NFS, kann<br />
einem Anwender so auf jedem System der Firma die gleiche Arbeitsumgebung zur<br />
Verfügung gestellt werden.<br />
Netzwerktransparenz<br />
6.2.3 Arbeiten am System<br />
Nach dem Einloggen kann man am System arbeiten. Je nach Aufgabenspektrum<br />
oder Präferenz kann dies in verschiedenen Umgebungen erfolgen. Auch die verwendeten<br />
Programme werden stark variieren. Eines ist jedoch für alle Benutzer<br />
gleich: Der Ort ihrer Arbeit und der Platz zum Speichern wichtiger Daten ist jeweils<br />
das Heimatverzeichnis (engl. home directory, im Deutschen oft auch Home-Verzeichnis<br />
genannt).<br />
Das Home-<br />
Verzeichnis<br />
183
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
Unter Linux und BSD besitzt jeder Benutzer sein eigenes Verzeichnis in /home,<br />
wohingegen dieses Verzeichnis unter anderen Unix-Systemen zum Beispiel auch<br />
unterhalb von /usr liegen kann. Im Normalfall hat der Benutzer nur in seinem<br />
eigenen Verzeichnis das Recht, Dateien anzulegen, zu ändern und zu löschen. 9<br />
Dafür besitzt er dort dann auch Narren- und Gestaltungsfreiheit. Wie er die Daten<br />
organisiert, steht jedem Benutzer absolut frei.<br />
Dateien verstecken<br />
Alle Programme können Dateien im jeweiligen Verzeichnis des Benutzers ablegen.<br />
Im Regelfall sind diese jedoch »versteckt«, werden also bei einem normalen Betrachten<br />
des Verzeichnisses nicht angezeigt. Die Namen versteckter Dateien beginnen<br />
alle mit einem Punkt; solche Dateien können natürlich unter Angabe spezieller<br />
Optionen dennoch angezeigt werden. In diesem Sinne sind sie also nicht versteckt,<br />
sondern werden im Normalfall schlicht <strong>aus</strong>geblendet, um dem Benutzer einen besseren<br />
Überblick über die von ihm selbst angelegten und bearbeiteten Dateien zu<br />
geben.<br />
Die Verzeichnisstruktur<br />
Wie Sie bereits wissen, besitzt Linux ein virtuelles Dateisystem, das von physischen<br />
Speichermedien auf eine Verzeichnisstruktur abstrahiert. Doch auch diese<br />
Verzeichnisstruktur selbst ist interessant, da sich das zugrunde liegende Konzept<br />
von anderen nicht Unix-artigen Betriebssystemen unterscheidet.<br />
Klassifikation<br />
Im Folgenden wollen wir die wichtigsten Verzeichnisse und ihre Bedeutung kurz<br />
erläutern. Dazu müssen vorher noch einige Begriffe geklärt werden, mit denen die<br />
Daten später klassifiziert werden:<br />
Dateien sind shareable, wenn sie auf einem Rechner im Netzwerk gespeichert sind und auch<br />
auf anderen Rechnern genutzt werden können. Ein gutes Beispiel dafür sind die Dateien in<br />
den Home-Verzeichnissen der User, wohingegen den Zugriff auf Systemressourcen auf dem<br />
lokalen Rechner kontrollierende Lockfiles eben nicht shareable – also unshareable –ist.<br />
Wie man sieht, spielt die Netzwerktransparenz also auch beim Dateisystem eine<br />
Rolle. Doch auch die Frage, wann und wie Daten verändert werden, ist für das<br />
Dateisystemlayout wichtig:<br />
Dateien sind statisch (engl. static), wenn sie nicht ohne die Intervention des Administrators<br />
geändert werden können. Im Gegensatz dazu stehen variable, also veränderbare Daten.<br />
Typische Beispiele für statische, also im Normalfall nicht schreibbare Daten, sind<br />
Programm-Binaries, Dokumentationen oder Systembibliotheken. Veränderbare Da-<br />
9 Ja, von Spezialfällen wie dem Verzeichnis für temporäre Dateien /tmp einmal abgesehen.<br />
184
Der erste Kontakt mit dem System 6.2<br />
teien sind zum Beispiel Logfiles, temporäre Dateien oder Datenbanken. Doch beginnen<br />
wir mit den wichtigsten Verzeichnissen und ihrer Bedeutung:<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
/bin<br />
Dieses Verzeichnis beinhaltet essenzielle (Shell-)Programme. Diese sind statisch<br />
und durch<strong>aus</strong> shareable.<br />
/boot<br />
Das /boot-Verzeichnis beinhaltet alle wichtigen Dateien zum Hochfahren des<br />
Systems, wozu vor allem der Kernel gehört. Diese Dateien sind im Allgemeinen<br />
statisch und nicht shareable, da sie durch verschiedene Treiber und die<br />
Konfiguration sehr systemspezifisch sind.<br />
/dev<br />
In diesem Verzeichnis finden sich die Gerätedateien. Je nach Kernel-Version und<br />
eingesetzter Technik kann dieses Verzeichnis auch nur virtuell sein. 10<br />
/etc<br />
Jegliche Konfigurationsdateien eines Systems sollten in dessen /etc-Verzeichnis<br />
abgelegt sein. Da sich eine Konfiguration selten selbst ändert, sind auch diese<br />
Daten statisch und aufgrund des personalisierenden Charakters einer Konfiguration<br />
eher als unshareable einzustufen. 11<br />
/home<br />
Das Home-Verzeichnis eines Users unter /home/username habenwirIhnenbereits<br />
vorgestellt. Hier werden die eingeloggten Benutzer in der Regel arbeiten.<br />
/lib<br />
In diesem Verzeichnis finden sich alle essenziellen Bibliotheken. In dem Verzeichnis<br />
/lib/modules/ finden sich somit auch die Module, die zur<br />
Laufzeit dynamisch in den Kernel geladen werden können.<br />
/mnt<br />
In /mnt sollten Wechseldatenträger wie CD-ROMs, DVDs oder USB-Sticks gemountet<br />
werden. Früher wurden dafür oft direkt Verzeichnisse unter / genutzt,<br />
was jedoch dem Konsens über die Verzeichnisstruktur widerspricht.<br />
/opt<br />
Damit Softwarepakete auch von Drittanbietern ins System integriert werden<br />
können, gibt es das /opt-Verzeichnis. Dort sollten entsprechend dem Firmen-<br />
Der Kernel<br />
10 Zum Beispiel beim mittlerweile obsoleten devfs.<br />
11 Natürlich hindert Sie niemand daran, das /etc-Verzeichnis im Netzwerk freizugeben. Inwieweit<br />
das sinnvoll ist, ist allerdings eine andere Frage – und nur darauf bezieht sich die<br />
unshareable-Aussage.<br />
185
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
oder Softwarenamen Unterverzeichnisse angelegt werden, in denen dann die<br />
jeweilige Software installiert werden kann.<br />
<br />
<br />
<br />
<br />
<br />
/proc (nur Linux)<br />
Im /proc-Verzeichnis findet sich ein gemountetes virtuelles Dateisystem, in dem<br />
sich Informationen über alle Prozesse und über das System abrufen lassen.<br />
Dieses Verzeichnis finden Sie allerdings nicht auf jedem System.<br />
/root<br />
Dies ist das Home-Verzeichnis von root. Da man als root nicht direkt am System<br />
arbeiten sollte, wird dieses Verzeichnis recht selten genutzt werden.<br />
/sbin<br />
In diesem Verzeichnis finden sich essenzielle System-Binaries.<br />
/tmp<br />
Dies ist das Verzeichnis für temporäre Daten. Im Regelfall werden während des<br />
Bootens alte, von der letzten Sitzung zurückgebliebene Dateien gelöscht.<br />
/usr<br />
Die /usr-Hierarchie ist die größte und wichtigste Ansammlung statischer, sharebarer<br />
Daten. Die wichtigsten Unterverzeichnisse finden Sie hier:<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
/usr/X11R6/<br />
Verzeichnis für die grafische Oberfläche X11<br />
/usr/bin/<br />
Benutzerprogramme (Binaries)<br />
/usr/include/<br />
Standardverzeichnis für Include-Dateien 12<br />
/usr/lib/<br />
Bibliotheken für Benutzerprogramme<br />
/usr/local/<br />
Extra-Hierarchie für selbstkompilierte Software, in sich wieder gen<strong>aus</strong>o gegliedert<br />
wie /usr<br />
/usr/sbin/<br />
nicht-essenzielle Systemprogramme<br />
/usr/share/<br />
architekturunabhängige Daten 13<br />
12 Siehe auch das Kapitel 30, »Softwareentwicklung«.<br />
13 Diese Daten müssen wie alle Daten in /usr read-only, also statisch, sein.<br />
186
Der erste Kontakt mit dem System 6.2<br />
<br />
/usr/src/<br />
Verzeichnis für Quellcode (optional)<br />
Aus den Charakteristika dieser Daten ergibt sich die Möglichkeit, das Verzeichnis<br />
/usr auf eine eigene Partition zu legen, es read-only zu mounten 14 und es<br />
schließlich im Netzwerk freizugeben und auf anderen Systemen zu mounten.<br />
<br />
/var<br />
Das /var-Verzeichnis umfasst ähnlich wie /usr eine ganze Hierarchie von Unterverzeichnissen<br />
mit speziellen Aufgaben. Im Gegensatz zu diesem sind die Daten<br />
in /var jedoch variabel und im Allgemeinen nicht shareable.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
/var/cache/<br />
anwendungsspezifische Cache-Daten<br />
/var/lib/<br />
variable Statusinformationen<br />
/var/local/<br />
variable Daten für /usr/local<br />
/var/lock/<br />
Lockdateien 15<br />
/var/log/<br />
Logdateien<br />
/var/opt/<br />
variable Daten für /opt<br />
/var/run/<br />
für laufende Prozesse relevante Daten 16<br />
/var/spool/<br />
Spooling-Daten wie beispielsweise zu druckende Dateien oder noch nicht<br />
abgeholte Mails<br />
/var/tmp/<br />
temporäre Dateien, die nicht bei einem Reboot gelöscht werden sollten<br />
14 Beim Aktualisieren des Systems muss dann natürlich ein Remount mit möglichem Schreibzugriff<br />
erfolgen, da sonst zum Beispiel keine Binaries ersetzt werden können.<br />
15 Diese Dateien stellen den exklusiven Zugriff auf bestimmte Ressourcen sicher: Ist eine bestimmte<br />
Datei vorhanden, so ist die zugehörige Ressource belegt. Erst nach dem Löschen<br />
der Datei kann wieder versucht werden, die Ressource anzufordern.<br />
16 Soll zum Beispiel ein Programm wie ein bestimmter Serverdienst nur einmal gestartet werden<br />
können, kann in /var/run eine Datei mit der Prozess-ID abgelegt werden. Bei einem<br />
versuchten zweiten Start des Programms kann dieses anhand der Datei nun feststellen, dass<br />
es schon läuft, und daher den Start verweigern.<br />
187
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
Auch bei /var kann sich die Speicherung der Daten auf einer eigenen Partition<br />
oder Platte anbieten, um bei knapper werdendem Plattenplatz immer noch<br />
etwas Platz auf der Root-Partition freihalten und damit ein funktionierendes<br />
System gewährleisten zu können.<br />
Mit Ausnahme des Home-Verzeichnisses wird man mit diesen Verzeichnissen in<br />
aller Regel jedoch nur als Administrator zu tun haben. Das liegt vor allem am<br />
Rechtesystem: Bis auf die temporären Verzeichnisse darf ein normaler Benutzer nur<br />
in sein Homeverzeichnis schreiben.<br />
Das Rechtesystem<br />
Diese Regelung ist sinnvoll, da so kein normaler Benutzer das System manipulieren<br />
oder umkonfigurieren kann. Wir wollen im Zusammenhang mit dem Rechtesystem<br />
als Erstes natürlich die Rechte etwas näher betrachten, die einem Benutzer gewährt<br />
oder nicht gewährt werden können:<br />
<br />
<br />
<br />
Write (w)<br />
Das Schreibrecht: Hat ein Benutzer dieses Recht (man spricht auch von einem<br />
Rechte-Flag oder Rechte-Bit) auf eine Datei, so kann er sie zum Schreiben öffnen<br />
oder sie auch löschen. Diese Berechtigung wird sinnvollerweise fast nur für<br />
eigene Dateien im Heimatverzeichnis des Benutzers benötigt und ist daher auch<br />
nur dort gesetzt. Auf Verzeichnissen bewirkt dieses Recht, dass ein Benutzer<br />
dort Dateien anlegen und löschen kann.<br />
Read (r)<br />
Das Leserecht: Dieses Recht erlaubt es einem Benutzer, lesend auf entsprechende<br />
Dateien zuzugreifen. Die Benutzer haben dieses Recht für die meisten Systemdateien<br />
wie Programme oder Dokumentationen. Nur in Ausnahmefällen wie<br />
bei wichtigen Passwortdateien bekommen normale Benutzer dieses Recht nicht<br />
zugesprochen.<br />
Execute (x)<br />
Dateien mit diesem Rechte-Flag können <strong>aus</strong>geführt werden. Entweder handelt<br />
es sich bei diesen Dateien um binäre Formate wie ELF oder um Skriptdateien<br />
bestimmter Sprachen wie Bash oder Perl. Bei letzteren muss jedoch in der ersten<br />
Zeile des Skripts der Interpreter genannt werden, mit dem die Datei <strong>aus</strong>geführt<br />
werden kann. Dieses Rechte-Flag wird in erster Linie verwendet, um zwischen<br />
Programmen und Daten zu differenzieren, und seltener, um festzulegen, wer<br />
ein bestimmtes Programm <strong>aus</strong>führen darf und wer nicht.<br />
Bei Verzeichnissen hat dieses Flag eine etwas andere Semantik: Dort wird nämlich<br />
durch das x-Flag der Zugriff auf ein Verzeichnis gesteuert. Wem dieses Recht<br />
nicht gewährt wird, dem bleibt das Wechseln in den entsprechenden Ordner<br />
verwehrt.<br />
188
Der erste Kontakt mit dem System 6.2<br />
Werden Rechte auf Dateien beziehungsweise Verzeichnisse vergeben, so müssen<br />
sich von einer bestimmten Rechtemaske auf einer Datei die Berechtigungen für<br />
jeden möglichen Benutzer ableiten lassen. Jedem Benutzer ist im System daher<br />
eine Benutzer-ID (UID, User ID) und mindestens eine Gruppen-ID (GID, Group ID)<br />
zugeordnet. Eine Datei wird nun auch einem Benutzer – nämlich dem Eigentümer<br />
beziehungsweise dem Ersteller der Datei – sowie einer Gruppe zugeordnet.<br />
Für den Rechtekontext bedeutet dies, dass man eine Rechtemaske setzen kann, die<br />
<strong>aus</strong> je einem Bit für Read, Write und Execute für den Eigentümer, die Gruppe und<br />
schließlich noch für den Rest der Welt besteht. Möchte ein Benutzer nun auf eine<br />
Datei zugreifen, so wird zuerst geprüft, ob er der Eigentümer dieser Datei ist. Ist<br />
dies der Fall, so wird die entsprechende Rechtemaske zur Prüfung der Gültigkeit<br />
des geforderten Zugriffs herangezogen. Ist der Benutzer nicht der Eigentümer, so<br />
wird geprüft, ob er in der Gruppe der Datei ist, um eventuell die Rechtemaske<br />
dieser Gruppe heranzuziehen. Ist auch dies nicht der Fall, werden automatisch die<br />
Rechte für den Rest der Welt gültig.<br />
root<br />
Eine Ausnahme in diesem Rechtekontext bildet der Benutzer root (UID 0), der<br />
immer auf alle Dateien Zugriff hat. Er ist, vom Eigentümer einer Datei abgesehen,<br />
auch der Einzige, der die Rechte auf eine Datei ändern kann. Dieser Superuser ist<br />
in der Regel der Administrator des Systems und verfügt sozusagen über absolute<br />
Macht durch den unbeschränkten Zugriff auf alle Dateien. Und wie man spätestens<br />
seit Spider-Man weiß: Mit großer Macht kommt große Verantwortung.<br />
Der Superuser<br />
Rechte und Hardware<br />
Rechte werden nur auf Dateien oder Verzeichnisse vergeben. Da jedoch zum Beispiel<br />
Geräte und bestimmte Ressourcen als Dateien im System repräsentiert sind<br />
und Unix an sich generell sehr dateiorientiert ist, ergibt sich so wieder ein konsistentes<br />
Gesamtbild.<br />
Auch sollte erwähnt werden, dass es problemlos möglich ist, mit mehreren Benutzern<br />
zur selben Zeit an einem System zu arbeiten. Natürlich ist ein PC in der<br />
Regel mit nur einem Bildschirm und nur einer Grafikkarte 17 <strong>aus</strong>gestattet, jedoch<br />
kann zum Beispiel über den SSH-Dienst das Remote-Arbeiten, also <strong>aus</strong>gehend von<br />
anderen Rechnern im Netzwerk, ermöglicht werden.<br />
17 Auch wenn man Linux durch<strong>aus</strong> so konfigurieren kann, dass zwei Grafikkarten und zwei Tastaturen<br />
für insgesamt zwei Benutzer zur Verfügung stehen.<br />
189
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
6.2.4 Herunterfahren<br />
Ein weiterer wichtiger Schritt im ersten Kontakt mit dem System ist das Herunterfahren.<br />
Wie heutzutage bei fast allen komplexeren Systemen üblich, kann man<br />
ein System nicht einfach beliebig von seiner Stromquelle trennen. Damit man es in<br />
einem konsistenten Zustand halten kann, müssen alle Programme<br />
<br />
<br />
<br />
ihre temporären Daten speichern,<br />
alle verwendeten Ressourcen freigegeben und<br />
das Dateisystem in einem konsistenten Zustand hinterlassen.<br />
Puffer und<br />
Caches leeren<br />
Vor allem die Problematik des Dateisystems ist offensichtlich, wenn man sich an<br />
das letzte Kapitel und die Tatsache erinnert, dass viele Daten zwischengespeichert<br />
und gepuffert werden, um die Performance des Systems zu erhöhen. Werden diese<br />
gepufferten Daten nicht zurückgeschrieben oder wird die Festplatte vielleicht sogar<br />
inmitten eines Schreibvorgangs unterbrochen, tritt ein Datenverlust auf oder es<br />
kommt zu inkonsistenten (Meta-)Daten auf der Festplatte.<br />
EinSystemherunterfahrenundsolcheProblemevermeidenkönnenSiemitdem<br />
Befehl shutdown:<br />
<br />
shutdown -h now<br />
Mit diesem Befehl hält man das System an (engl. halt). Dazu wird das System<br />
in den Runlevel 0 überführt, wobei alle gestarteten Dienste beendet werden.<br />
Schließlich werden alle verbleibenden Prozesse über ein SIGTERM aufgefordert,<br />
sich zu beenden, um sie dann nach kurzer Zeit mit einem SIGKILL auf die »harte<br />
Tour« durch den Kernel zu beenden.<br />
Die Prozesse werden gesondert beendet, damit alle offenen Dateien noch geschlossen<br />
werden können. Ignorierte man diese im Prozesskontrollblock vermerkten<br />
Daten, würden eventuell bisher nur gepufferte Schreibzugriffe nicht<br />
<strong>aus</strong>geführt und gingen somit verloren.<br />
<br />
shutdown -r now<br />
Mit diesem Befehl wird das System neu gestartet (engl. reboot) und dazu in den<br />
Runlevel 6 überführt. Alle übrigen Aktionen, vom Herunterfahren der beim<br />
Systemstart von init aktivierten Dienste bis zum Senden der Signale an alle<br />
Prozesse, entsprechen dem Vorgehen beim Systemhalt.<br />
Natürlich muss man diese Befehle nicht auf der Shell eingeben, sondern kann<br />
auch von einer grafischen Oberfläche wie KDE <strong>aus</strong> ein System herunterfahren.<br />
Allerdings hat man auf der Shell die Möglichkeit, anstelle von now einen genauen<br />
Zeitpunkt anzugeben, zu dem das System heruntergefahren oder neu gestartet wird.<br />
190
Der erste Kontakt mit dem System 6.2<br />
Auch kann man hier eine Nachricht eingeben, die vor der shutdown-Aktion an alle<br />
eingeloggten Nutzer gesendet wird.<br />
6.2.5 Wie Laufwerke bezeichnet werden<br />
Wenn Sie ein Windows-Anwender sind, dann kennen Sie Laufwerksbezeichnungen<br />
als Buchstaben (etwa C: oder D:). Unter Linux ist das Prinzip ähnlich, Laufwerke<br />
werden hier allerdings als Gerätedateien repräsentiert und heißen daher anders.<br />
Wie für Gerätedateien üblich, sind Dateien, die Laufwerksgeräte repräsentieren, im<br />
Verzeichnis /dev zu finden.<br />
Laufwerke werden (im Falle von CD-, DVD-, ATA- und SCSI-Laufwerken) mit sdX<br />
bezeichnet, wobei anstelle des X ein Kleinbuchstabe eingesetzt wird. /dev/sda ist<br />
etwa eine typische Festplattenbezeichnung, gen<strong>aus</strong>o wie /dev/sdb. Eskannsichbei<br />
den jeweiligen Geräten aber auch um CD-Laufwerke und Ähnliches handeln.<br />
Sollten Sie noch über IDE-Festplatten verfügen, so werden diese unter Linux mit<br />
/dev/hda, /dev/hdb usw. bezeichnet.<br />
Auch einzelne Partitionen sind unter Linux als Dateien vorhanden. So ist die erste<br />
Partition der Festplatte /dev/sda als /dev/sda1 ansprechbar, die zweite Partition als<br />
/dev/sda2 und so fort.<br />
Die genannten Bezeichner für Festplatten sind für die Systemkonfiguration von<br />
großer Bedeutung. Sie werden etwa verwendet, um anzugeben, wo eine Platte im<br />
Dateisystem eingehängt werden soll. Es kann allerdings sein, dass eine Festplatte<br />
umkonfiguriert und dadurch ihr Bezeichner verändert wird, was wiederum die<br />
Systemkonfiguration empfindlich treffen kann. Aus diesem Grund sind viele Distributionen<br />
dazu übergegangen, sogenannte UUIDs (Universally Unique Identifier) zu<br />
verwenden. Dabei handelt es sich um eindeutige Bezeichner für Laufwerke, die auch<br />
nach einer Umkonfiguration erhalten bleiben können. Sollten Sie also einmal eine<br />
Festplatte umstecken, so müssen Sie die Systemkonfiguration nicht ändern. Eine<br />
UUID ist eine eindeutige und zudem recht lange Hex-Zahl. Über das Programm<br />
blkid können Sie sich die UUIDs Ihrer Partitionen anzeigen lassen.<br />
sdX<br />
hdX<br />
Partitionen<br />
UUIDs<br />
$ blkid<br />
/dev/sda1: UUID="7b898fa6-391e-4b81-888c-48ef10d7a95f"<br />
SEC_TYPE="ext2" TYPE="ext3"<br />
/dev/sdb1: UUID="7b76eae9-1d58-43b2-856e-f4c6b7a914f9"<br />
SEC_TYPE="ext2" TYPE="ext3"<br />
/dev/sdb2: UUID="c646f84c-2c4c-446b-ac09-9d398099867e"<br />
TYPE="swap"<br />
191
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
/dev/sdb3: UUID="018ad305-97b0-40a6-b8c0-54734cf6e6b3"<br />
SEC_TYPE="ext2" TYPE="ext3"<br />
Listing 6.2 Das Programm blkid zeigt die UUIDs des Systems an.<br />
Die erste Spalte enthält die Partitionsbezeichnung. Darauf folgt die eigentliche UUID<br />
und zwei Dateisystemtyp-Angaben. Die Angabe TYPE steht für den eigentlichen<br />
Dateisystemtyp (hier also »ext3«). Kann ein Dateisystem auch als ein anderes Dateisystem<br />
gemountet werden (das Dateisystem ext3 kann auch als ext2-Dateisystem<br />
eingehängt werden, ist also rückwärtskompatibel), so gibt SEC_TYPE (secondary<br />
filesystem type) diesenalternativenTypenan.<br />
Möchten Sie nur die UUID einer bestimmten Partition angezeigt bekommen, könnenSiederenDateinamenauchanblkid<br />
übergeben:<br />
$ blkid /dev/sdb3<br />
/dev/sdb3: UUID="018ad305-97b0-40a6-b8c0-54734cf6e6b3"<br />
SEC_TYPE="ext2" TYPE="ext3"<br />
Listing 6.3 Die UUID von /dev/sdb3 anzeigen<br />
Die UUIDs sind als Links im Dateisystem präsent, können also auch durch das<br />
ls-Programm angezeigt werden.<br />
$ ls -l /dev/disk/by-uuid<br />
insgesamt 0<br />
lrwxrwxrwx 1 root root 10 2010-09-12 10:12<br />
018ad305-97b0-40a6-b8c0-54734cf6e6b3 -> ../../sdb3<br />
lrwxrwxrwx 1 root root 10 2010-09-12 10:12<br />
7b76eae9-1d58-43b2-856e-f4c6b7a914f9 -> ../../sdb1<br />
lrwxrwxrwx 1 root root 10 2010-09-12 10:12<br />
7b898fa6-391e-4b81-888c-48ef10d7a95f -> ../../sda1<br />
lrwxrwxrwx 1 root root 10 2010-09-12 10:12<br />
c646f84c-2c4c-446b-ac09-9d398099867e -> ../../sdb2<br />
Listing 6.4 UUIDs mit ls anzeigen<br />
Laufwerke unter BSD<br />
Unter BSD werden Laufwerke anders bezeichnet als unter Linux. Auch sind die<br />
Standarddateisysteme andere als unter Linux, doch dazu mehr in Kapitel 28.<br />
Unter OpenBSD und NetBSD werden Serial-ATA- und IDE-Laufwerke mit wdN, also<br />
wd0, wd1 und so fort bezeichnet. Beachten Sie hier, dass die erste Stelle hier bei<br />
0 beginnt, und nicht – wie bei Linux – bei a (also etwa sda). Dasselbe gilt für<br />
SCSI-Festplatten, deren Bezeichnung mit sd0 beginnt, gefolgt von sd1.<br />
192
Bewegen in der Shell 6.3<br />
Partitionen tragen hingegen Zahlenbezeichner, womit sich Partitionsbezeichner wie<br />
wd0a oder wd0c ergeben. Auch hier ist zu beachten, dass die Ziffern bei Linux das<br />
Laufwerk an sich angeben, nicht die Partition. Details zu beiden Treibern erhalten<br />
Sie unter beiden Derivaten in den Manpages sd und wd.<br />
Auch unter FreeBSD sind die Bezeichner für Laufwerke unterschiedlich. IDE-Festplatten<br />
werden mit adN, alsoad0, ad1 (und so fort) bezeichnet. SCSI- und USB-<br />
Platten werden hingegen mit daN, IDE-CD/DVD-Laufwerke mit acdN und SCSI-<br />
CD/DVD-Laufwerke mit cdN bezeichnet. Für die alten (maximal vier) verschiedenen<br />
DOS-Partitionen verwendet FreeBSD den Ausdruck Slice, so bezeichnet ad0s1<br />
etwa die erste Slice einer IDE-Festplatte und ad0s1a die erste Partition im ersten<br />
Slice der ersten IDE-Festplatte. da1s3a bezeichnet hingegen die erste Partition der<br />
dritten Slice der zweiten Platte.<br />
6.3 BewegeninderShell<br />
Wir haben die Shell bereits als wichtigen Bestandteil der Unix-Philosophie vorgestellt<br />
und sind auch in den Beispielen bisher auf Befehle eingegangen. Im Folgenden<br />
wollen wir, um den Anspruch dieses Kapitels zu erfüllen, kurz die <strong>Grundlagen</strong> des<br />
Arbeitens in der Shell vorstellen.<br />
6.3.1 Das Prompt<br />
Die Eingabeaufforderung der Shell besteht nicht nur <strong>aus</strong> einem blinkenden Cursor<br />
für die Eingabe, sondern auch noch <strong>aus</strong> dem Prompt. Dieses gibt meist den Kontext<br />
der Arbeit durch die Anzeige des Rechner- und Benutzernamens sowie des<br />
Arbeitsverzeichnisses wieder. Allerdings kann jeder Benutzer seinen Prompt auch<br />
personalisieren und sogar farbig gestalten.<br />
$<br />
user@host$<br />
user@host:/home/user$<br />
/root#<br />
Listing 6.5 Mögliche Prompts<br />
Dass Informationen wie der Rechner- und Benutzername angezeigt werden, hilft<br />
vor allem beim Arbeiten auf verschiedenen Rechnern im Netzwerk. Das Arbeitsverzeichnis<br />
hilft dabei, den Ausgangspunkt relativer Pfade zu bestimmen.<br />
193
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
6.3.2 Absolute und relative Pfade<br />
Unix-Systeme kennen keine Laufwerke und sprechen alle Speichermedien über den<br />
VFS-Layer und einen Verzeichnisbaum an. So ergeben sich zwei verschiedene Arten,<br />
wie man Dateien und Verzeichnisse referenzieren kann.<br />
Bei der Angabe eines absoluten Pfades wird der Name immer von der Wurzel / des Dateisystems<br />
<strong>aus</strong> angegeben.<br />
Unnötige<br />
Redundanz<br />
Dies kann jedoch zu recht langen Eingaben und redundanten Angaben führen,<br />
falls ein Benutzer hauptsächlich in einem bestimmten Verzeichnis arbeitet. Daher<br />
besitzt jeder Prozess – und damit natürlich auch jede Shell – mit dem aktuellen<br />
Arbeitsverzeichnis einen aktuellen Kontext. Von diesem Verzeichnis <strong>aus</strong> kann man<br />
Verzeichnis- oder Dateinamen auch relativ angeben.<br />
Ein relativer Pfad beginnt nicht mit der Wurzel des Dateisystems, sondern wird relativ zum<br />
aktuellen Arbeitsverzeichnis des Prozesses interpretiert, indem das Arbeitsverzeichnis vor<br />
den relativen Pfad gesetzt und das Ergebnis schließlich als absoluter Pfad gelesen wird.<br />
Erst so wird es möglich, dass man zum Beispiel einen Texteditor mit text.txt als<br />
Argument aufrufen kann, anstatt sich über den Pfad /home/user/text.txt auf die<br />
Datei zu beziehen.<br />
6.3.3 pwd<br />
Sollte der Prompt einer Shell einmal weniger <strong>aus</strong>sagekräftig sein, so kann man sich<br />
das Arbeitsverzeichnis auch mit dem pwd-Befehl anzeigen lassen. Die Abkürzung<br />
steht für print working directory.<br />
$ pwd<br />
/home/jploetner<br />
Listing 6.6 Arbeitsverzeichnis mit pwd <strong>aus</strong>geben<br />
Ein neuer Prozess entsteht unter Unix stets als Kopie eines bereits bestehenden<br />
Prozesses. Als Kopie erbt er alle Eigenschaften wie eben auch das Arbeitsverzeichnis.<br />
6.3.4 cd<br />
Natürlich kann das Arbeitsverzeichnis der Shell auch durch einen bestimmten Befehl<br />
gewechselt werden. Der cd-Befehl ist die Abkürzung für change directory und<br />
erwartet eine Pfadangabe als Argument. Diese kann selbstverständlich wieder re-<br />
194
Bewegen in der Shell 6.3<br />
lativ oder absolut gemacht werden, wobei man zwei Spezialfälle relativer Pfade<br />
unterscheidet:<br />
».«<br />
Jedes Verzeichnis enthält eine Referenz auf sich selbst, die der Kürze halber<br />
mit einem einfachen Punkt bezeichnet wird. Diesen Punkt benötigt man vor<br />
allem, wenn man eine <strong>aus</strong>führbare Datei starten möchte, die sich vielleicht im<br />
Homeverzeichnis des Benutzers befindet. Normalerweise sucht die Shell nur in<br />
bestimmten Ordnern – diese Ordner werden in einer speziellen Shell-Variable,<br />
dem PATH, gespeichert – nach <strong>aus</strong>führbaren Dateien, so dass man den Pfad zu<br />
einem an anderer Stelle gespeicherten Programm explizit angeben muss:<br />
Referenz auf<br />
sich selbst<br />
$ ./schach<br />
Listing 6.7 Programm <strong>aus</strong> dem aktuellen Verzeichnis starten<br />
Dieser Pfad referenziert nun eine Datei schach im aktuellen Verzeichnis. Für den<br />
cd-Befehl braucht man die Selbstreferenz jedoch selten, da man schließlich das<br />
Verzeichnis wechseln möchte.<br />
»..«<br />
Mit den zwei Punkten bezeichnet man das nächsthöhere Verzeichnis. Zusammen<br />
mit den direkt referenzierbaren Unterverzeichnissen ergibt sich so die komplette<br />
Navigation in der Shell:<br />
$ pwd<br />
/home/jploetner<br />
$ cd ..<br />
$ pwd<br />
/home<br />
$ cd jploetner<br />
$ pwd<br />
/home/jploetner<br />
Listing 6.8 Navigation in der Shell<br />
Interessanterweise hat <strong>aus</strong> Konsistenzgründen auch das Wurzelverzeichnis /<br />
einen solchen Backlink. Dieser zeigt jedoch wieder auf das Wurzelverzeichnis<br />
selbst.<br />
Am Beispiel von cd kann man auch sehr gut sehen, dass Shellbefehle in der Regel<br />
im Erfolgsfall keine Meldung <strong>aus</strong>geben. Das Kommando erledigt nur seine Aufgabe,<br />
und wenn diese zur Zufriedenheit des Benutzers <strong>aus</strong>geführt werden konnte, muss<br />
es dies nicht extra kundtun. Etwas anderes gilt natürlich im Fehlerfall, also wenn<br />
man mit cd in ein nicht existierendes Verzeichnis wechseln will:<br />
Stumme Befehle<br />
195
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
$ cd swendzel<br />
-bash: cd: swendzel: No such file or directory<br />
$<br />
Listing 6.9 Ein fehlgeschlagener cd-Aufruf<br />
Was dieses -bash in der obigen Ausgabe zu suchen hat, erfahren Sie im nächsten<br />
Kapitel, wo wir den Unterschied zwischen Programmen und Shell-Builtins erklären.<br />
6.4 Arbeiten mit Dateien<br />
Unser nächster Schwerpunkt soll das Arbeiten mit Dateien sein. Zuerst wollen wir<br />
dabei betrachten, wie man sich Dateien in der Shell anzeigen lassen kann.<br />
6.4.1 ls<br />
Dateien eines<br />
Verzeichnisses<br />
anzeigen<br />
Für die Auflistung von Dateien in der Shell ist der ls-Befehl zuständig. Ohne<br />
Argument zeigt ls den Inhalt des Arbeitsverzeichnisses an, allerdings kann man<br />
sich die Dateien jedes beliebigen Verzeichnisses durch dessen Angabe als Argument<br />
auflisten lassen:<br />
$ pwd<br />
/usr/src/linux-2.6.10<br />
$ ls<br />
arch crypto fs ipc MAINTAINERS<br />
...<br />
CREDITS drivers init lib mm<br />
REPORTING-BUGS sound<br />
$ ls /home<br />
jploetner mploetner aploetner<br />
Listing 6.10 Dateien auflisten mit ls<br />
Versteckte Dateien<br />
anzeigen<br />
Im Normalfall – also wie hier im Listing ohne Angabe weiterer Optionen – zeigt<br />
ls nur Dateien und Verzeichnisse an. Mit einem Punkt beginnende und somit<br />
»versteckte« Elemente eines Verzeichnisses werden <strong>aus</strong>geblendet. Möchte man sich<br />
diese Dateien dennoch alle anzeigen lassen, sollte man das -a-Flag benutzen:<br />
$ ls<br />
test test.c<br />
$ ls -a<br />
test test.c .vimlog<br />
Listing 6.11 Versteckte Dateien anzeigen<br />
196
Arbeiten mit Dateien 6.4<br />
Natürlich kann ls auch viele mit einer Datei verknüpfte Metadaten wie Rechte oder<br />
Eigentümer und Gruppe anzeigen. Man will mit anderen Worten ein langes Listing,<br />
das man mit dem -l-Flag erhält:<br />
$ ls -l<br />
-rwxr-xr-x 1 jploetner users 28 05-03-13 22:03 test<br />
-rw-r--r-- 1 jploetner users 371 05-02-10 13:40 test.c<br />
Listing 6.12 Lange und <strong>aus</strong>führliche Dateilistings<br />
In diesem Beispiel können Sie das Rechtesystem auch in der Praxis sehen: Beide<br />
DateienhabendenEigentümerjploetner und gehören zur Gruppe users. Ganz<br />
am Anfang sieht man auch drei Dreiertupel, die in der Reihenfolge »Eigentümer«,<br />
»Gruppe« und »Sonstige« jeweils über die Berechtigungen r (read), w (write) und x<br />
(execute) Auskunft geben. Wird der entsprechende Buchstabe in der Ausgabe von ls<br />
angezeigt, so wird das Recht gewährt. Andernfalls signalisiert ein Minus das Fehlen<br />
der entsprechenden Berechtigung. Was die weiteren von ls angezeigten Daten im<br />
Einzelnen bedeuten und was man mit ls sonst noch machen kann, erfahren Sie in<br />
Teil III, »Die Shell«, und in der Kommandoreferenz ab Seite 1220.<br />
6.4.2 more, less und most<br />
Möchte man sich textuelle Dateien (etwa Shellskripte, ein README oder Dateien<br />
<strong>aus</strong> /etc) ansehen, so kann man sich zum Beispiel zweier Programme bedienen: more<br />
und less. Beide Tools sind sogenannte Pager und zeigen den Inhalt einer Datei als<br />
Text interpretiert an. Sie unterscheiden sich dabei nur in ihrer Bedienung, wobei<br />
less etwas benutzerfreundlicher ist als more.<br />
Dateien anzeigen<br />
Bei more kann man nur mittels der Enter-Taste jeweils eine Zeile tiefer scrollen, less<br />
dagegen erlaubt eine intuitivere und umfassendere Bedienung mittels Cursor- und<br />
den Bildlauftasten. Bei beiden Pagern kann man in der angezeigten Datei suchen,<br />
indem man den Slash (/), gefolgt vom Suchbegriff, eintippt. Über die Taste N kann<br />
man schließlich zur nächsten Fundstelle des Suchbegriffs springen.<br />
Mit dem Programm most können Sie gegenüber less nochmals an Bedienkomfort<br />
gewinnen, denn most most kann farbige Ausgaben verschiedener Eingabe-Typen<br />
(etwa Manpages) erstellen.<br />
Sowohl less, alsauchmost können mehrere Dateien gleichzeitig geöffnet haben<br />
(das nächste Fenster erhält man durch :n,beiless kann das vorherige zudem mit :p<br />
erreicht werden). In most können auch Fenster aufgeteilt werden, sodass Sie mehrere<br />
geöffnete Dateien gleichzeitig betrachten können (Strg + X und anschließend<br />
2 drücken).<br />
Beenden können Sie alle drei Programme durch die Taste Q.<br />
197
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
6.4.3 Und Dateitypen?<br />
Einige Verwirrung bei der Arbeit mit Dateien entsteht hinsichtlich der Verwendung<br />
von Dateiendungen. Endungen wie .jpg oder .txt sollten ja im Regelfall einen Rückschluss<br />
auf den Dateiinhalt erlauben, also im Beispiel auf eine Bild- beziehungsweise<br />
Textdatei hinweisen.<br />
Eine konsistente<br />
Lösung<br />
Unter Linux wie auch unter BSD und anderen Unix-Versionen ist der Punkt nun<br />
ein gültiger Bestandteil des Dateinamens. Mit Ausnahme eines Punkts als ersten<br />
Buchstaben im Dateinamen – der bekanntlich eine Datei »versteckt« – kann man<br />
den Punkt so oft man will, oder eben auch gar nicht, verwenden. Der Kernel kann<br />
nur Programme starten, keine Bild- oder Textdateien. Auf Dateien wird unabhängig<br />
vom Dateityp über ein einheitliches Interface mittels open(), read() und auch<br />
write() zugegriffen. Für das System sind alle Dateien nur eine Folge von Bits und<br />
Bytes. Die Anwendung allein ist dafür zuständig, diese Daten zu interpretieren.<br />
Folglich sind Erweiterungen wie .jpg und .txt nur für Sie als Benutzer relevant. Sie<br />
können auf den ersten Blick erkennen, um welche Art Datei es sich handelt. Wenn<br />
Sie nun aber unbedingt eine Musikdatei in einem Texteditor bearbeiten wollen,<br />
können Sie dies tun – dem System ist das egal.<br />
Eine Einschränkung gilt jedoch für grafische Oberflächen wie KDE oder GNOME:<br />
Wenn Sie mit einem Klick auf eine Textdatei diese Datei in einen Editor laden und<br />
anschließend bearbeiten wollen, so muss eine gewisse Verknüpfung vom Dateityp<br />
zu der für diesen Typ bevorzugten Anwendung bestehen. Der Einfachheit halber<br />
bietet es sich dann natürlich an, diese Zuordnung aufgrund der Dateiendungen<br />
vorzunehmen. 18<br />
file<br />
Analyse des Inhalts<br />
Eine weitere Möglichkeit ist der Versuch, den Inhalt aufgrund bestimmter charakteristischer<br />
Muster zu erkennen. Für die Kommandozeile ist hier das file-Tool das<br />
Programm der Wahl: Wird es mit einer zu untersuchenden Datei aufgerufen, gibt<br />
es den aufgrund einer Inhaltsanalyse vermuteten Dateityp <strong>aus</strong>:<br />
$ file test.c<br />
test.c: ASCII C program text<br />
$ file test<br />
test:ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for<br />
GNU/Linux 2.2.0, dynamically linked (uses shared libs), not stripped<br />
Listing 6.13 In Aktion: file<br />
18 Diese »Einfachheit« und die Wahlmöglichkeit gilt für die Programmierer der grafischen<br />
Oberfläche, die Ihnen als Nutzer dann schließlich eine Möglichkeit zur Verknüpfung von<br />
Dateitypen zu Programmen anbieten.<br />
198
Der Systemstatus 6.5<br />
Je nach Dateityp kann die Analyse dabei relativ kurz oder auch etwas <strong>aus</strong>führlicher<br />
<strong>aus</strong>fallen.<br />
6.5 Der Systemstatus<br />
Selbstverständlich können Sie in einem gewissen Rahmen auch den Systemstatus<br />
kontrollieren. Diesem Thema ist ein eigenes Kapitel zur Administration gewidmet,<br />
jedoch wollen wir vorab einige grundlegende und einfache Programme vorstellen.<br />
6.5.1 uname<br />
Mit dem uname-Befehl können Sie unter Linux zum Beispiel feststellen, welche<br />
Kernel-Version gebootet ist. Aber auch unter anderen Unix-Systemen kann man<br />
Näheres über die eingesetzte Betriebssystemversion oder die Rechnerarchitektur<br />
erfahren. Alle verfügbaren Informationen können Sie sich mit dem -a-Parameter<br />
anzeigen lassen:<br />
Informationen<br />
über das System<br />
$ uname -a<br />
Linux athlon2000 2.6.8-2-k7 #1 Tue Mar 22 14:14:00 \<br />
EST 2005 i686 GNU/Linux<br />
Listing 6.14 uname<br />
Das Format der <strong>aus</strong>gegebenen Daten kann dabei von Unix-Version zu Unix-Version<br />
variieren, da nicht alle dieselbe Implementierung des Programms verwenden.<br />
6.5.2 uptime<br />
Ein weiterer interessanter Befehl ist uptime. Mit diesem Kommando kann man sich<br />
darüber informieren, wie lange ein System nun schon ohne Neustart läuft – vor<br />
allem bei Servern kann dies interessant, aber oft auch wichtig sein.<br />
Laufzeit eines<br />
Systems<br />
$ uptime<br />
3:21:38 up 4:03, 1 user, load average: 2.09,0.85,0.59<br />
Listing 6.15 uptime<br />
Aus der Ausgabe lesen Sie zunächst die aktuelle Systemzeit, gefolgt von der Uptime<br />
des Rechners und einigen Daten zur Auslastung ab.<br />
6.5.3 date<br />
Mit dem Befehl date können Sie die Systemzeit sowie das Datum abfragen und<br />
Zeit anzeigen<br />
mit date<br />
199
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
auch setzen. Ohne Optionen zeigt das Tool die Uhrzeit samt Datum an:<br />
$ date<br />
So Apr 10 19:09:22 CEST 2005<br />
Listing 6.16 Die Zeit <strong>aus</strong>lesen<br />
Zeit neu setzen<br />
Das Setzen der Zeit geschieht nun über den Parameter -s, gefolgt von der neuen<br />
Zeit. Damit die Benutzer mit einem solchen Befehl keine Spielchen treiben und<br />
vielleicht zeitkritische Anwendungen durcheinanderbringen, ist das Setzen der Systemzeit<br />
nur dem Administrator root erlaubt:<br />
# date -s 20:36:40<br />
So Apr 10 20:36:40 CEST 2005<br />
Listing 6.17 Die Zeit setzen<br />
Auch wenn es etwas ungewöhnlich ist, aber der Befehl date ist auch für die Uhrzeit<br />
zuständig. Es gibt zwar einen time-Befehl, doch hat dieser nichts mit der Uhrzeit,<br />
sondern vielmehr mit der Zeitmessung zu tun und wird von uns im Kapitel zur<br />
Softwareentwicklung behandelt.<br />
6.6 Hilfe<br />
Zu guter Letzt fehlt uns für eine komplette Betrachtung des Einstiegs noch die<br />
Möglichkeit, Hilfe zu erhalten. Schließlich sind die Optionen und Möglichkeiten<br />
vieler Programme so reichhaltig, dass man sie kaum komplett im Kopf behalten<br />
kann. Vor allem in nicht ganz alltäglichen Situationen wird man gerne einmal auf<br />
Befehlsreferenzen zurückgreifen.<br />
6.6.1 Manpages<br />
Eine solche Befehlsreferenz finden Sie zum einen natürlich am Ende dieses Buches,<br />
zum anderen aber auch in den Manpages. Diese sind das traditionelle Hilfesystem<br />
für Unix und somit (wie auch nicht anders zu erwarten) in erster Linie über die<br />
Shell erreichbar.<br />
Handbuchseiten<br />
auf dem PC<br />
Zu fast allen Befehlen und Programmen gibt es eine Handbuchseite (engl. manual<br />
page), die <strong>aus</strong> der Shell her<strong>aus</strong> mit dem man-Kommando betrachtet werden kann.<br />
Das Scrollen funktioniert dabei wie gewohnt, und das Suchen erfolgt wie bei less<br />
oder auch beim vi über die /-Taste, gefolgt vom Such<strong>aus</strong>druck und Betätigen der<br />
Taste N zum Aufrufen der nächsten Fundstelle.<br />
200
Hilfe 6.6<br />
$ man ls<br />
Listing 6.18 Aufrufen der Manpage für ls<br />
Manpages enthalten dabei üblicherweise eine kurze Beschreibung des Programms<br />
sowie eine komplette Referenz der verfügbaren Kommandozeilenoptionen. Nur<br />
selten findet sich ein <strong>aus</strong>führlicheres Beispiel in einer Manpage. Und so passt diese<br />
Hilfe wieder zur Unix-Philosophie: Erfahrene Nutzer wollen nur kurz die Syntax<br />
bestimmter Optionen nachschlagen und sich dafür nicht durch seitenlange Einführungen<br />
quälen müssen.<br />
Sections<br />
Für manche Stichwörter gibt es mehr als nur ein Hilfethema und somit auch mehr<br />
als eine Manpage. Ein gutes Beispiel dafür ist das Programm man selbst: Es gibt zu<br />
diesem Thema einmal eine Hilfeseite zur Bedienung des man-Programms und eine<br />
Hilfeseite zur Erstellung von Manpages. Damit man Hilfeseiten zu unterschiedlichen<br />
Themenkomplexen unterscheiden kann, gibt es unterschiedliche Sections<br />
(Abschnitte), in die die Manpages eingeteilt werden:<br />
Unterschiedliche<br />
Themenkomplexe<br />
1. <strong>aus</strong>führbare Programme oder Shell-Befehle<br />
2. Systemaufrufe (Kernel-Funktionen)<br />
3. Bibliotheksaufrufe (Funktionen in Systembibliotheken)<br />
4. spezielle Dateien (gewöhnlich in /dev)<br />
5. Dateiformate und Konventionen, z. B. /etc/passwd<br />
6. Spiele<br />
7. Makropakete und Konventionen, z. B. man(7), groff(7)<br />
8. Systemadministrationsbefehle (in der Regel nur für root)<br />
9. Kernel-Routinen (linux-spezifisch)<br />
Die Sektionen sind im System als einfache Verzeichnisse realisiert, in denen dann<br />
jeweils die Manpages der entsprechenden Sektionen abgelegt sind. Die Manpages<br />
selbst sind wiederum nur Dateien in bestimmter Formatierung.<br />
Möchte man explizit auf eine Seite innerhalb einer Sektion zugreifen, so gibt man<br />
beim Aufruf von man einfach die Sektionsnummer des eigentlichen Hilfethemas an:<br />
$ man 1 write<br />
$ man 2 write<br />
Listing 6.19 Unterschiedliche Man-Sektionen<br />
201
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
In diesem Beispiel wird zuerst die Manpage für das <strong>aus</strong>führbare Programm write<br />
<strong>aus</strong> der Sektion 1 und danach die Manpage zum Syscall write() <strong>aus</strong> der Sektion 2<br />
aufgerufen. Lässt man diese explizite Angabe der Sektionsnummer weg und tippt<br />
nur man write, so wird die Manpage <strong>aus</strong> der niedrigsten Sektion – also in unserem<br />
Fall die Manpage <strong>aus</strong> Sektion 1 zum Programm write – angezeigt. Um die<br />
Verwirrung zu reduzieren, wird für den Bezug auf eine bestimmte Sektion diese in<br />
Klammern nach dem Befehl angegeben, also beispielsweise write(2).<br />
whatis<br />
Das kleine Programm whatis hilft uns nun, alle Sektionen zu einem bestimmten<br />
Thema her<strong>aus</strong>zufinden. Das Tool ist dabei lediglich ein Frontend für den Aufruf von<br />
man mit dem Parameter -f:<br />
$ whatis write<br />
write (1)<br />
write (2)<br />
$ man -f write<br />
write (1)<br />
write (2)<br />
- send a message to another user<br />
- write to a file descriptor<br />
- send a message to another user<br />
- write to a file descriptor<br />
Listing 6.20 whatis<br />
Angezeigt werden also der Titel der Manpage, die Sektionsnummer sowie eine<br />
kurze Beschreibung des Seiteninhalts.<br />
apropos<br />
Suchbegriff<br />
angeben<br />
Eine etwas weiter gefasste Suche ermöglicht das Tool apropos, das wiederum nur<br />
Frontend für man mit der Option -k ist:<br />
$ apropos write<br />
...<br />
kwrite (1)<br />
llseek (2)<br />
login (3)<br />
...<br />
- KDE text editor<br />
- reposition read/write file offset<br />
- write utmp and wtmp entries<br />
Listing 6.21 apropos<br />
Hier werden alle Manpages angezeigt, bei denen im Namen der Seite oder in der<br />
Kurzbeschreibung auf das Suchwort Bezug genommen wird. Beide Tools – whatis<br />
und apropos – ergänzen somit das Manpage-Hilfesystem von Unix.<br />
202
Zusammenfassung 6.7<br />
6.6.2 GNU info<br />
Ähnlich wie man funktioniert das Programm info der GNU-Community. Die Bedienung<br />
ist etwas anders, aber eigentlich auch recht intuitiv. Der Grund für ein eigenes<br />
Hilfesystem dieser Open-Source-Gruppe liegt in der Abkürzung GNU selbst: GNU is<br />
Not Unix. Mit info sollte ein eigenes Hilfesystem für ein komplett freies GNU-basiertes<br />
Betriebssystem geschaffen werden. Mittlerweile spricht man teilweise von<br />
GNU/Linux, um <strong>aus</strong>zudrücken, dass Linux zwar den Systemkern, aber GNU die<br />
wichtigsten grundlegenden Systemtools zur Verfügung stellt. Aber natürlich gibt es<br />
alle GNU-Infoseiten auch als Manpages.<br />
GNU is Not Unix<br />
6.6.3 Programmdokumentation<br />
Solche Manual- oder Infoseiten sind natürlich meist ein zentraler Bestandteil der<br />
Dokumentation von Softwarepaketen. Außerdem werden oft sogenannte READ-<br />
ME-Dateien nach /usr/doc oder /usr/share/doc installiert, die noch einmal im Detail<br />
Auskunft über spezielle Funktionen und Aspekte der Bedienung geben.<br />
Eine Auflistung aller verfügbaren Optionen und damit eine ähnliche Ausgabe wie<br />
in den Manpages kann man oft durch die Angabe der Parameter --help oder -h auf<br />
der Kommandozeile erhalten. Ansonsten hilft meistens auch die Homepage weiter,<br />
die man bei Open-Source-Software eigentlich immer über eine der folgenden Seiten<br />
findet:<br />
<br />
<br />
SourceForge: http://www.sourceforge.net<br />
Freshmeat: http://www.freshmeat.net<br />
Alternativ gibt es für jede Distribution auch noch zahlreiche Foren auf den entsprechenden<br />
Internetseiten. Bei Linux-Fragen sind oft diverse Mailinglisten und<br />
Newsgroups recht hilfreich. Ansonsten hilft natürlich auch immer die Suchmaschine<br />
Ihrer Wahl, gefüttert mit passenden Suchbegriffen.<br />
6.7 Zusammenfassung<br />
In diesem Kapitel haben Sie anhand der Unix-Philosophie die <strong>Grundlagen</strong> von Linux<br />
und allen verwandten Unix-Systemen kennengelernt – und hoffentlich auch<br />
verstanden. Dabei sind wir vor allem auf die Sicht- und weniger auf die Funktionsweise<br />
des Systems eingegangen.<br />
Sicher sind Sie über einige interessante Anmerkungen zum Dateisystemlayout, zu<br />
den Rechten oder auch zu den Dateitypen gestolpert. Außerdem hatten Sie bereits<br />
203
6 <strong>Grundlagen</strong> <strong>aus</strong> <strong>Anwendersicht</strong><br />
Ihren ersten Kontakt mit der Shell, den wir in den nächsten Kapiteln 19 intensivieren<br />
werden. Im Anschluss an diese Shell-<strong>Grundlagen</strong> werden wir uns in Teil IV mit der<br />
Administration und Verwaltung eines Linux-Systems befassen.<br />
6.8 Aufgaben<br />
Philosophisches<br />
Ein Bekannter belästigt Sie wieder einmal mit unqualifizierten Aussagen über Linux.<br />
Unter anderem erwähnt er die unnötige und anachronistische Komplexität des<br />
Systems. Alles sei einfach zu umständlich realisiert. Was antworten Sie ihm?<br />
Richtige Partitionierung<br />
Sie müssen als Administrator eines großen Rechenzentrums einen neuen Linux-Server<br />
aufsetzen. Der Server soll verschiedene (Daten-)Verzeichnisse für die Benutzer<br />
freigeben. Wie gestalten Sie vom Prinzip her die Partitionierung?<br />
19 Ja, wir sprechen im Plural – dieses Buch erspart Ihnen ein weiteres Buch zur Shell. Und das<br />
ist gut so. ;-)<br />
204
»Die Neugier steht immer an erster Stelle eines Problems,<br />
das gelöst werden will.«<br />
– Galileo Galilei<br />
7 Die Shell<br />
In diesem Kapitel werden wir uns mit einem Thema beschäftigen, das für die<br />
Arbeit mit allen Unix-artigen Systemen zentral ist. Dabei ist es fast egal, ob es sich<br />
um Linux, *BSD, Solaris, AIX, HP-UX, Mac OS X oder was auch immer handelt. Das<br />
Thema dieses Kapitels ist die Shell. Doch ...<br />
7.1 Was ist eine Shell?<br />
Ganz kurz und verständlich: Die Shell ist das Programm, das nach dem Konsolen-Login<br />
gestartet wird und in dem Befehle (etwa zum Start weiterer Programme)<br />
eingegeben werden können. 1 Die Shell ist somit das Arbeitsinstrument Nummer<br />
Eins der klassischen Unix-Umgebung.<br />
OpenBSD/i386 (eygo.sun) (ttyC1)<br />
login: swendzel<br />
Password:<br />
swendzel$<br />
Listing 7.1 Ein Login mit Shell-Start<br />
Dass Sie sich in einer Shell befinden, bemerken Sie oftmals durch den sogenannten<br />
Eingabe-Prompt, der Sie zur Eingabe eines Befehls auffordert. Dieser kann verschieden<br />
<strong>aus</strong>sehen – hier sind einige Beispiele für Shell-Prompts:<br />
user$<br />
host#<br />
#<br />
$<br />
1 Natürlich werden nach dem Login oftmals noch diverse andere Programme, etwa mail oder<br />
fortune, gestartet, doch lassen wir diese hier zunächst noch außer Acht.<br />
207
7 Die Shell<br />
%<br />
bash2#<br />
Listing 7.2 Typische Shell-Prompts<br />
Sofern Sie sich in einer Shell befinden, sollte es kein Problem sein, einen Befehl<br />
<strong>aus</strong>zuführen. Probieren Sie es am besten gleich einmal <strong>aus</strong>. 2 Starten Sie einfach die<br />
Bourne-Shell, die unter den meisten Unix-Systemen die Standardshell ist. 3 Dazu<br />
gebenSiedenBefehl/bin/sh ein.<br />
user$ /bin/sh<br />
user$<br />
Listing 7.3 Start der Bourne-Shell<br />
Sofern Sie sich bereits in der Bourne-Shell befanden (was durch<strong>aus</strong> der Fall sein<br />
kann), wird sich Ihnen kein interessantes Bild auf dem Bildschirm bieten – Sie erhalten<br />
nämlich genau den gleichen Eingabe-Prompt wie bisher. Allerdings arbeiten<br />
Sie nun mit der neuen Shell. Würden Sie diese Shell nun verlassen, befänden Sie<br />
sich wieder in der Login-Shell.<br />
7.1.1 Eine Shell verlassen<br />
Um eine Shell wieder zu verlassen, verwendet man das Kommando exit. Durch<br />
diesen Befehl kann grundsätzlich jede Standard-Shell verlassen werden. Geben Sie<br />
dieses Kommando einmal in der soeben gestarteten Bourne-Shell ein, danach werden<br />
Sie sich wieder in der Login-Shell befinden. Für eine Login-Shell gilt noch eine<br />
besondere Bedingung: Login-Shells können durch das Kommando logout verlassen<br />
werden. Anschließend wird die Shell-Session des Benutzers beendet, und dieser wird<br />
zum erneuten Login aufgefordert.<br />
user$ exit<br />
user$ logout<br />
OpenBSD/i386 (eygo.sun) (ttyC1)<br />
login:<br />
Listing 7.4 Subshell und Login-Shell verlassen<br />
2 Und genießen Sie es – vielleicht spüren Sie ja schon die Faszination ...<br />
3 Unter Linux ist die Standardshell die bash und die vermeintliche Bourne-Shell nur ein Hardlink<br />
auf die bash.<br />
208
Was ist eine Shell? 7.1<br />
Weiterhin können Shells auch verlassen werden, in dem man ihnen ein EOF (»end<br />
of file«) über die Tastenkombination Strg+D sendet.<br />
7.1.2 nologin<br />
Je nach verwendetem Betriebssystem steht Ihnen unter Linux und BSD ein Programm<br />
zur Verfügung, das den Login eines Accounts unterbindet, was nicht mit<br />
einer kompletten Deaktivierung des Accounts gleichzusetzen ist. Das Ausführen<br />
von Prozessen ist nämlich auch unter Accounts ohne gültige Login-Shell möglich.<br />
Dieses Programm, oft handelt es sich um /sbin/nologin oder auch /bin/false,<br />
wird als Login-Shell des Benutzers in der Benutzerkonfiguration angegeben (näheres<br />
hierzu erfahren Sie im weiteren Verlauf des Buches).<br />
Normalerweise wird beim erfolgreichen Login-Versuch, also bei der Eingabe des<br />
korrekten Passworts eines solchen Benutzers, eine Meldung wie »This account is<br />
currently not available.« <strong>aus</strong>gegeben. Unter OpenBSD können Sie diese Meldung<br />
jedoch an Ihre Wünsche anpassen, indem Sie den <strong>aus</strong>zugebenden Text selbst in die<br />
Datei /etc/nologin.txt eintragen. Diese Datei muss normalerweise erst von Hand erstellt<br />
werden. Weitere Informationen hierzu liefert Ihnen die Manpage nologin(8).<br />
$ echo "Account gesperrt." > /etc/nologin.txt<br />
$ chmod 644 /etc/nologin.txt<br />
$ nologin<br />
Account gesperrt.<br />
Listing 7.5 Eine eigene Meldung via nologin <strong>aus</strong>geben<br />
7.1.3 /etc/shells<br />
In der Datei /etc/shells stehen die Pfadnamen gültiger Login-Shells. Das bedeutet,<br />
dass all diese Shells in der Passwortdatei für einen Benutzer angegeben werden<br />
können. Außerdem können diese Shells beim Wechsel der Login-Shell durch das<br />
Programm chsh (das wir gleich besprechen werden) verwendet werden.<br />
$ cat /etc/shells<br />
# /etc/shells: valid login shells<br />
/bin/ash<br />
/bin/csh<br />
/bin/sh<br />
/usr/bin/es<br />
/usr/bin/ksh<br />
/bin/ksh<br />
/usr/bin/rc<br />
/usr/bin/tcsh<br />
209
7 Die Shell<br />
/bin/tcsh<br />
/bin/sash<br />
/usr/bin/esh<br />
/bin/bash<br />
/bin/rbash<br />
/bin/dash<br />
/bin/zsh<br />
/usr/bin/zsh<br />
Listing 7.6 Der typische Inhalt von /etc/shells<br />
Möchten Sie selbst installierte Shells als Login-Shells verwenden, so müssen Sie<br />
einen entsprechenden Eintrag für die neuen Shells in der /etc/shells eintragen. Sofern<br />
Sie eine Shell über ein Paketmanagementsystem installieren (was fast immer der<br />
Fall sein dürfte), werden die Einträge der Datei /etc/shells meistens automatisch<br />
angepasst.<br />
7.1.4 Die Login-Shell wechseln<br />
Beim Login in ein System wird die Shell aufgerufen, die Ihrem Account in der Datei<br />
/etc/passwd zugewiesen wurde. Diese Login-Shell lässt sich jedoch ganz einfach<br />
ändern. Dazu wird das Programm chsh verwendet. Nachdem Sie Ihr Passwort dort<br />
eingegeben haben, geben Sie den Pfad zu der Shell ein, die in Zukunft verwendet<br />
werden soll. Ein Blick in /bin verschafft Ihnen eine Übersicht über die installierten<br />
Shells. 4 chsh modifiziert anschließend den Eintrag in der Passwort-Datei des<br />
Systems.<br />
$ chsh<br />
Password:<br />
Ändere die Login-Shell für swendzel<br />
Geben Sie einen neuen Wert an oder ENTER für den Standardwert<br />
Login-Shell [/bin/bash]: /bin/csh<br />
$<br />
Listing 7.7 Die Login-Shell ändern<br />
7.2 Welche Shells gibt es?<br />
Ende der 70er-Jahre wurde mit der Unix-Version 7 von AT&T die erste Bourne-<br />
Shell (kurz sh) <strong>aus</strong>geliefert. Diese Shell wurde in der Programmiersprache C (jedoch<br />
unter Verwendung Algol-68-ähnlicher Makros) entwickelt und stellte bereits<br />
sh<br />
4 Unter einigen Systemen (etwa OpenBSD) landen Shells, die als Ports installiert wurden, in<br />
/usr/local/bin.<br />
210
Welche Shells gibt es? 7.2<br />
einige wichtige Funktionalität zur Verfügung, wie etwa Pipes, sowie Ein- und Ausgabeumlenkung.<br />
Benannt wurde die Bourne-Shell nach ihrem Entwickler Stephen<br />
Bourne.<br />
Die sogenannte Job Shell ist eine Weiterentwicklung der Bourne-Shell. Neu in dieser<br />
Shell waren die namensgebenden Jobs. Diese Jobs erlauben es (wie Sie später noch<br />
genau erfahren werden), Programme im Hintergrund ablaufen zu lassen, anzuhalten<br />
und später fortzusetzen.<br />
Neben der Bourne-Shell wurde in den ersten Jahren der BSD-Geschichte die C-Shell<br />
(csh) entwickelt. Ihr Begründer war Bill Joy, ein BSD-Mitentwickler und Gründer<br />
von Sun Microsystems. Joy war jedoch auch an diversen anderen wichtigen Projekten,<br />
etwa an der Weiterentwicklung der TCP/IP-Protokollfamilie, beteiligt. Die<br />
C-Shell wurde zum ersten Mal mit 4.1BSD publiziert. Zu ihren populärsten Features<br />
zählen die Funktionalität als Interpreter einer eigenen Skriptsprache (die, wie<br />
der Name C-Shell erahnen lässt, an die Syntax der Programmiersprache C angelehnt<br />
ist), die Kommando-History, die Job-Kontrolle und die interaktive Datei- und Benutzernamenerweiterung.<br />
Die C-Shell ist heute in ihrer Bedeutung nicht mehr der<br />
Bourne-Shell gleichzusetzen. In einem umfassenden Handbuch wie diesem werfen<br />
wir allerdings dennoch in Kapitel 12 einen Blick auf die C-Shell.<br />
jsh<br />
csh<br />
Diese beiden Vertreter, also Bourne-Shell und C-Shell, stellen die beiden grundlegenden<br />
Shellvarianten unter Unix-Systemen dar. Die meisten populären Folgeentwicklungen<br />
bauen entweder auf der C-Shell und ihrer Syntax oder auf der Bourne-<br />
Shell und deren Syntax auf. Es gibt zwar auch andere Shells, die ihre Syntax keiner<br />
der beiden Shells angepasst haben, etwa die Scheme-Shell (shsh), die an die Syntax<br />
der Programmiersprache Scheme angelehnt ist, doch sind diese Shells in der Praxis<br />
weitgehend bedeutungslos. Einige Weiterentwicklungen kombinieren auch die<br />
Features beider Shells (C-Shell und Bourne-Shell).<br />
Die TENEX-C-Shell (tcsh) ist eine C-Shell-Weiterentwicklung von Christos Zoulas.<br />
Diese Shell bietet gegenüber der eigentlichen C-Shell einige Verbesserungen in<br />
Sachen Benutzerfreundlichkeit.<br />
Die von David Korn entwickelte Korn-Shell (ksh) basiert auf den Eigenschaften<br />
und der Syntax der Bourne-Shell. Allerdings übernimmt die Korn-Shell auch einige<br />
Features der C-Shell. Die Korn-Shell ist Bestandteil des POSIX-Standards und in der<br />
Version ksh93 seit März 2000 als Quelltext zu haben.<br />
Da die Korn-Shell jedoch nicht immer frei war, entwickelte man die Public-Domain-<br />
Korn-Shell (pdksh). Diese Shell beinhaltet alle Funktionalität des ksh88-POSIX-Standards<br />
und wird unter OpenBSD als Standardshell verwendet.<br />
Die Almquist-Shell (ash) ist eine kleine, der Bourne-Shell ähnliche Shell und stellt<br />
unter einigen BSD-Derivaten die Standardshell dar.<br />
tcsh<br />
ksh<br />
pdksh<br />
ash<br />
211
7 Die Shell<br />
Die Debian-Almquist-Shell (dash) basiert auf der NetBSD-Version der Shell ash. Un-<br />
ter Debian wird die dash als Ersatz für die ash eingesetzt, und einige Distributionen<br />
verwenden die dash anstelle der langsameren bash für ihre Startskripts (etwa Ubuntu).<br />
In der Entwicklung der Hardened-Linux-Distribution benutzten wir die dash<br />
unter anderem als Skriptsprache für die automatische Generierung von Packages.<br />
Die dash ist wie die ash größtenteils kompatibel mit der Bourne-Shell.<br />
dash<br />
Die Bourne-Again-Shell, kurz bash, ist wie die meisten aktuellen Shells ein Open-<br />
Source-Projekt. 5 Die bash ist POSIX-Standard-konform und baut auf der Syntax der<br />
Bourne-Shell auf. Sie beherrscht sowohl Features der Bourne- und der Korn-Shell<br />
als auch solche der C-Shell. Die bash ist die Standardshell unter Linux-Systemen.<br />
bash<br />
zsh<br />
Ein wahrer Bolide unter den Unix-Shells ist die Z-Shell (zsh). Sie vereint die Features<br />
der bash, csh und tcsh. Sie bietet diverse individuelle Features wie die Nutzung<br />
der Bourne- und der C-Shell-Syntax, die Möglichkeit, Themes zu verwenden und<br />
sogar Module wie etwa zftp 6 zu laden. Näheres zu dieser Shell erfahren Sie in<br />
[Steph99A] und [Wendzel03A].<br />
7.3 Welche Shell für dieses Buch?<br />
Nun ist es leider so, dass nicht unter jedem System die gleichen Shells in der<br />
Standardinstallation enthalten sind. Es steht zwar überall die C-Shell zur Verfügung,<br />
diese verwendet heutzutage jedoch kaum noch jemand.<br />
Für welche Shell entscheidet man sich in einem Buch, das sowohl Linux als auch<br />
BSD behandelt? Unter Linux steht generell immer die bash zur Verfügung, was<br />
schon einmal sehr gut ist. Unter OpenBSD ist die pdksh, unter Net- und FreeBSD<br />
die ash die Standard-Shell. Sie alle basieren auf der Syntax der Bourne-Shell, und<br />
die Shellskripte für den Systemstart sind sowohl unter Linux als auch unter den<br />
BSD-Derivaten für diese Shells geschrieben.<br />
In diesem Buch wird, wann immer es sinnvoll ist, die grundlegende Bourne-Shell<br />
verwendet, zu der alle anderen Vertreter der Bourne-Shell-Familie (ash, dash, ksh,<br />
pdksh, bash und zsh) abwärtskompatibel sind. Für die Konfiguration des Prompts<br />
und in der Einführung konzentrieren wir uns auf die bash.<br />
Kurz gesagt: Wir haben einen Weg gefunden, Ihnen genau das beizubringen, was<br />
Sie eigentlich überall anwenden können, egal ob Sie BSD, Linux, Solaris, HP/UX,<br />
AIX, VxWorks, QNX oder was auch immer verwenden.<br />
5 Die bash wird vom GNU-Projekt unter der GNU General Public License entwickelt.<br />
6 Hiermit ist es möglich, sich direkt in der Shell an einem FTP-Server anzumelden, Interprozesskommunikation<br />
mit den Dateien eines FTP-Servers (über Pipes) durchzuführen u.v.m.<br />
212
Konsolen 7.4<br />
Unter BSD muss die bash zunächst <strong>aus</strong> den Packages oder Ports installiert werden.<br />
Falls Sie nicht wissen, wie dies zu bewerkstelligen ist, bleiben Sie einfach bei der<br />
Bourne-Shell. Kapitel 14 demonstriert am Beispiel von OpenBSD, wie man Ports<br />
und Packages installiert.<br />
Damit die bash nach der Installation auch als Login-Shell fungieren kann, muss für<br />
sie ein entsprechender Eintrag in der Datei /etc/shells hinterlegt werden. Unter BSD<br />
(vergessen Sie nicht, den Pfad anzupassen) kann dies durch den folgenden Befehl<br />
bewerkstelligt werden:<br />
# echo "/bin/bash" >>/etc/shells<br />
Listing 7.8 Die bash als Login-Shell zur Verfügung stellen<br />
7.4 Konsolen<br />
Unter Linux, BSD und ähnlichen Systemen steht Ihnen nicht nur eine einzige Konsole<br />
zur Verfügung. Sofern nicht die grafische Oberfläche läuft, landen Sie nach<br />
dem Systemstart normalerweise auf der ersten Konsole. Je nach Konfiguration gibt<br />
es meist zwischen fünf und acht, wobei nicht alle immer als eigentliche Shellkonsole<br />
verwendet werden. Auf Konsole fünf oder sieben läuft in der Regel die grafische<br />
Oberfläche, und auf einer weiteren Konsole könnten Systemmeldungen angezeigt<br />
werden.<br />
Der Wechsel zwischen den Konsolen erfolgt über die Tastenkombination Strg + Alt<br />
+ Funktionstaste, also etwa Strg + Alt + F2 für die zweite Konsole.<br />
Wie wechseln?<br />
7.5 screen<br />
Ein weiteres wichtiges Werkzeug innerhalb einer Shell ist screen. Wird es gestartet,<br />
so wird der ganze Bildschirm des Terminals für das Programm verwendet. Ohne<br />
Parameter startet screen einfach nur eine Shell. Was aber ist das Besondere an<br />
diesem Programm?<br />
Im Folgenden werden die Begriffe Fenster und Terminal der Einfachheit halber synonym<br />
verwendet.<br />
Ganz einfach: screen ermöglicht es Ihnen, parallel auf mehreren virtuellen Terminals<br />
zu arbeiten, obwohl Sie in Wirklichkeit nur eines verwenden. Nehmen wir<br />
einmal an, Sie loggen sich über ein Programm wie SSH oder Telnet auf einem entfernten<br />
Rechner ein. Dort möchten Sie ein Programm schreiben. Um dies möglichst<br />
213
7 Die Shell<br />
komfortabel zu erledigen, benötigen Sie zumindest ein Terminal, in dem ein Texteditor<br />
läuft, mit dem man den Quellcode editieren kann, und eines, mit dem man<br />
das Programm kompilieren, <strong>aus</strong>führen und debuggen kann. Mit screen ist genau<br />
das möglich, obwohl Sie sich nur ein einziges Mal einloggen müssen.<br />
Das Programm wird durch einen Aufruf von screen (für eine Shell) oder screen<br />
[programm] gestartet. Screen legt dafür ein erstes virtuelles Terminal an. Anschließend<br />
können Sie in der gestarteten Shell beziehungsweise mit dem gestarteten<br />
Programm wie gewohnt arbeiten.<br />
Nehmen wir das obige Beispiel nun zur Hand und erleichtern wir uns die Arbeit an<br />
einem Programm. Dazu könnte man beispielsweise einen Editor (etwa vi) starten. 7<br />
Ein weiteres<br />
Terminal<br />
Terminalwechsel<br />
Nun erstellen Sie durch die Tastenkombination Strg + A und anschließendes<br />
Drücken der Taste C (für create) ein neues virtuelles Terminal. Sodann wechselt<br />
screen auch gleich die Ansicht auf das neu erstellte Terminal, das mit einer Shell auf<br />
Eingaben wartet. Sie könnten darin nun den Compiler oder Ähnliches anwerfen.<br />
Um zwischen den existierenden virtuellen Terminals zu wechseln, nutzen Sie die<br />
Tastenkombination Strg + A und drücken anschließend eine Taste zwischen 0 und<br />
9. Damit steht die Möglichkeit zur Verfügung, zwischen insgesamt zehn virtuellen<br />
Terminals zu wechseln (sofern Sie tatsächlich so viele erzeugen möchten).<br />
Abbildung 7.1 screen mit Fensterliste<br />
Eine weitere Möglichkeit ist der Weg über die Fensterliste (Window List). In die<br />
Fensterliste gelangen Sie über die Tastenkombination Strg + A und anschließendes<br />
Drücken der Anführungszeichen-Taste. Mit den Cursortasten wechseln Sie dort<br />
zwischen den einzelnen Fenstern (man sieht deren Nummer und Name).<br />
Namen für<br />
Terminals<br />
Einzelnen Terminals kann man über die übliche Tastenkombination sowie anschließendes<br />
Drücken der Taste A auch Namen verpassen. Diese erscheinen dann in der<br />
7 Der vi wird in späteren Kapiteln noch genauer behandelt. Sie beenden ihn durch Esc (Wechsel<br />
in den Kommandomodus) und den Befehl »:q«.<br />
214
Die Shell anwenden 7.6<br />
Fensterliste. Nach Strg + A und anschließend W erscheint am unteren Fensterrand<br />
übrigens eine Namensliste der Terminals. Drückt man dann beispielsweise die 1, so<br />
landet man auf dem ersten davon.<br />
Ein Fenster kann durch die Tastenkombination Strg + A und anschließendes<br />
Drücken von K (kill) beendet werden. Sie können die Fenster auch schließen,<br />
indem Sie die Shell und/oder das gestartete Programm (in dieser Shell) verlassen. 8<br />
Fenster schließen<br />
Hat man das letzte Fenster zerstört, wird eine Meldung wie »screen is terminating«<br />
auf dem Terminal angezeigt und man befindet sich wieder in der Ausgangsshell.<br />
7.6 Die Shell anwenden<br />
Bei der Anwendung der Shell ist generell zwischen zwei verschiedenen Arten der<br />
Verwendung zu unterscheiden. Die erste Möglichkeit besteht darin, sie als Arbeitsumgebung,<br />
also als Benutzerschnittstelle, zu verwenden. Man startet <strong>aus</strong> ihr her<strong>aus</strong><br />
Programme, etwa einen Editor, mit denen man dann Arbeiten verrichtet.<br />
Die zweite Verwendungsmöglichkeit besteht in der Programmierung von Shellskripts.<br />
Jede Shell hat dafür ihre eigene Shellskript-Sprache. Wir unterscheiden<br />
hierbei primär die Syntax der Bourne-Shell- und der C-Shell-Familie.<br />
Um Ihnen eine Vorstellung vom Unterschied der Syntax beider Varianten zu geben,<br />
ist im Folgenden jeweils ein Beispielskript zur Bourne- und zur C-Shell aufgeführt.<br />
Beide Shellskripts erledigen die gleiche Aufgabe, sehen aber doch recht unterschiedlich<br />
<strong>aus</strong>. Im Laufe dieses Kapitels werden wir uns mit der Syntax der Bourne-Shell<br />
befassen, wonach Sie dann die meisten Shellskripte des Systems verstehen können.<br />
#!/bin/sh<br />
for file in dateiA dateiB dateiC; do<br />
cp $file /backup/<br />
done<br />
if [ "$a" = "test" ]<br />
then<br />
echo $a<br />
fi<br />
Listing 7.9 Bourne-Shell-Skript<br />
8 Was natürlich davon abhängt, ob man das Programm direkt durch screen oder erst in einer<br />
Shell innerhalb eines virtuellen Terminals gestartet hat.<br />
215
7 Die Shell<br />
#!/bin/csh<br />
foreach file ( dateiA dateiB dateiC )<br />
cp $file backup/<br />
end<br />
if ($a == "test") then<br />
echo $a<br />
endif<br />
Listing 7.10 C-Shell-Skript<br />
Shellskripte dienen primär zur Automatisierung von administrativen Arbeitsschritten oder<br />
zur Initialisierung und zum Start wichtiger Programme beim Booten des Systems.<br />
Dieses Kapitel wird sich zunächst mit den <strong>Grundlagen</strong> der Shell befassen. Anschließend<br />
werden wir uns in Kapitel 8 den regulären Ausdrücken und den Tools sed und<br />
awk widmen. Außerdem werden wir uns in Kapitel 10 mit Editoren und in Kapitel<br />
11 mit Bourne-Shell-Programmierung, also Shellskriptprogrammierung, befassen.<br />
Doch bevor wir mit den <strong>Grundlagen</strong> beginnen, sei noch etwas zu den Vor- und<br />
Nachteilen der Shellskriptprogrammierung gesagt.<br />
Im Vergleich zu anderen interpretierten Programmiersprachen wie Perl sind Shellskripts<br />
äußerst langsam. Dies liegt besonders daran, dass einzelne Programme erst<br />
<strong>aus</strong> dem Skript her<strong>aus</strong> – oft auch mehrmals hintereinander neu – gestartet werden<br />
müssen, was sehr viel Zeit kostet. Im Vergleich zu hochperformanten Sprachen<br />
wie C++, bei denen die Programme direkt als Binärdatei vorliegen und kein Skript-<br />
Interpreter vonnöten ist, ist die Shell natürlich noch viel langsamer.<br />
Der Vorteil der Shell liegt allerdings in der Einfachheit und Flexibilität, mit der<br />
Skripts erstellt und gewartet werden können. Shellskriptprogrammierung ist einfach<br />
und effizient. Da Sie eigentlich nur auf bereits vorhandene Programme zugreifen<br />
müssen, ist es nicht notwendig, komplexe Algorithmen zu implementieren, was in<br />
der Regel auch gar nicht möglich ist. Sie sollten in der Shell also keinen Binärbaum<br />
implementieren wollen, dafür kann aber beispielsweise binnen kürzester Zeit und<br />
mit einem Bruchteil des Aufwandes, den Sie in Sprachen wie C oder Java benötigen<br />
würden, ein Skript für das Systembackup erstellt werden.<br />
Zudem sind Shellskripts unter Unix-Systemen sehr portabel, zumindest wenn man<br />
sich an gewisse Standards hält. Oftmals müssen Sie gar nichts anpassen und wenn<br />
doch, dann in der Regel nur Pfade oder Programmparameter. Die Wahrscheinlichkeit,<br />
dass ein bash-Skript, das unter Linux geschrieben wurde, auch unter Solaris<br />
oder OpenBSD läuft, ist groß.<br />
216
<strong>Grundlagen</strong> der Shellnutzung 7.7<br />
7.7 <strong>Grundlagen</strong> der Shellnutzung<br />
Der folgende Abschnitt zählt zu den wichtigsten des Buches, da hier die elementaren<br />
Kenntnisse für die Handhabung der Shell vermittelt werden.<br />
7.7.1 Programme starten<br />
In der Shell werden Programme entweder durch Angabe des Programmnamens<br />
oder durch des genauen Pfades zum Programm gestartet.<br />
Beim Programmstart über den Namen durchsucht die Shell ihre interne Liste von<br />
Verzeichnissen, die sie in der angegebenen Reihenfolge nach dem jeweiligen Programmnamen<br />
durchsucht. Wird das Programm in einem dieser Verzeichnisse gefunden,<br />
so wird es gestartet.<br />
Relative<br />
Pfadangabe<br />
Diese Verzeichnisliste ist in der Variablen $PATH gespeichert. Sie lernen im weiteren<br />
Verlauf des Kapitels noch den Umgang mit solchen Variablen. Um jedoch schon<br />
einmal einen Blick auf den Inhalt dieser Variablen zu werfen, können Sie den<br />
folgenden Befehl <strong>aus</strong>führen:<br />
$ echo $PATH<br />
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:<br />
/usr/games<br />
Listing 7.11 Inhalt der PATH-Variablen <strong>aus</strong>geben<br />
7.7.2 Kommandos aneinanderreihen<br />
Unter Unix ist es generell möglich, mehr als nur ein Kommando pro Befehl durchzuführen.<br />
Ein Befehl endet erst, wenn er mit der Eingabetaste an die Shell geschickt<br />
wird. Ein Kommando kann von einem anderen einfach durch ein Semikolon (;)<br />
getrennt werden.<br />
Stellen Sie sich einmal vor, Sie möchten fünf verschiedene Suchaktionen hintereinander<br />
starten, die aber jeweils eine unbestimmt lange Zeit benötigen werden.<br />
Eventuell müssen Sie so stundenlang vor dem Computer sitzen und warten, bis<br />
eine Suche nach der anderen durchgelaufen ist, um die jeweils folgende zu starten.<br />
Viel einfacher wäre es da, wenn Sie alle Suchkommandos aneinanderreihen und<br />
einfach in einer Stunde mal vorbeischauen könnten, ob der Rechner die Aufgaben<br />
inzwischen erledigt hat. So müssen Sie nicht nach jeder einzelnen Suche die nächste<br />
starten.<br />
217
7 Die Shell<br />
Der Operator ;<br />
Bewerkstelligt wird eine solche Reihung von Kommandos im einfachsten Fall durch<br />
Verwendung des Trennungsoperators, des Semikolons. Ungeachtet dessen, ob es<br />
Probleme mit einem der Kommandos in der Liste gibt, die Sie der Shell übergeben,<br />
laufen alle Kommandos hintereinander ab. Dies bedeutet allerdings auch, dass<br />
Probleme entstehen können, wenn ein Befehl auf dem anderen aufbaut. 9<br />
$ ls VerZeiCh ; uname ; find / -name Datei<br />
/bin/ls: VerZeiCh: No such file or directory // ls<br />
Linux<br />
// uname<br />
/usr/local/share/Datei<br />
// find<br />
/home/user/Datei<br />
Listing 7.12 Der Trennungsoperator<br />
Der Operator &&<br />
Verwenden Sie hingegen den &&-Operator, so werden die dadurch aneinandergereihten<br />
Kommandos nur so lange <strong>aus</strong>geführt, wie der Ablauf der in der Liste angegebenen<br />
Kommandos erfolgreich ist. Die Abarbeitung der Kommandoreihe wird<br />
also abgebrochen, sobald ein Fehler auftritt. Dies ist allerdings nicht ganz exakt<br />
formuliert, denn ein Abbruch gilt nur dann als Fehler, wenn ein Programm mit<br />
einem entsprechenden Fehlercode endet.<br />
Unter Unix-Systemen gibt jedes Programm beim Beenden einen Wert an die Shell<br />
zurück. Dieser Wert ist entweder 0, wenn das Programm erfolgreich <strong>aus</strong>geführt<br />
wurde, oder ungleich 0, wenn ein Problem auftrat. In der C-Programmierung wird<br />
beispielsweise durch das return-Schlüsselwort in der Funktion int main(...) ein<br />
solcher Wert zurückgegeben.<br />
Wenn wir das obige Beispiel nun erneut aufrufen und dabei die Semikolon-Operatoren<br />
durch &&-Verknüpfungen ersetzen, werden wir feststellen, dass die Kommandoreihe<br />
nicht weiter <strong>aus</strong>geführt wird, nachdem das ls-Kommando fehlgeschlagen<br />
ist.<br />
$ ls VerZeiCh && uname && find / -name Datei<br />
/bin/ls: VerZeiCh: No such file or directory<br />
Listing 7.13 Der Operator &&<br />
9 Beispielsweise könnte das Kommando, das ein Backup erstellt, fehlschlagen und das Kommando,<br />
das dieses Backup auf einen Storage-Server übertragen soll, dann eine beschädigte<br />
Datei übertragen.<br />
218
<strong>Grundlagen</strong> der Shellnutzung 7.7<br />
Der ||-Operator<br />
Das Gegenstück zum &&-Operator ist der ||-Operator. Anders als bei && werden<br />
die durch || aneinandergereihten Kommandos nur dann <strong>aus</strong>geführt, wenn das<br />
vorherige Kommando fehlschlägt. Man verwendet diesen Operator besonders gerne<br />
zur Ausgabe von Fehlermeldungen und zum Ausführen von »Plan B«.<br />
pgrep X >/dev/null || echo "use 'startx' to start X"<br />
Listing 7.14 Beispielanwendung des ||-Operators<br />
7.7.3 Mehrzeilige Kommandos<br />
Oftmals ist es recht unübersichtlich und unangenehm, sehr lange Kommandolisten<br />
oder lange Einzelbefehle zu übergeben. Viel einfacher ist es hingegen, diese auf<br />
mehrere Zeilen zu verteilen. Diese mehrzeiligen Kommandos werden mit einem<br />
Backslash (\) realisiert.<br />
Im Folgenden übergeben wir find das zweite und dritte Element des Argumentvektors<br />
in einer neuen Zeile:<br />
$ find /usr/local/share/doc/usd \<br />
-name bc \<br />
/usr/share/doc/usd/06.bc/bc<br />
Listing 7.15 Ein Kommando über mehrere Zeilen<br />
7.7.4 Alias, shell-intern oder -extern?<br />
Wie Sie bereits wissen, ist es in der Shell möglich, normale Programme zu starten.<br />
Weiterhin gibt es die Möglichkeit, shell-interne Kommandos <strong>aus</strong>zuführen.<br />
Je nach Shell sind verschiedene Kommandos in der Shell selber integriert. Die bash<br />
enthält beispielsweise ein eigenes kill-Kommando. Wird also in der bash kill<br />
aufgerufen, so wird nicht das Programm <strong>aus</strong> dem Verzeichnis /bin, sondern das<br />
gleichnamige Shell-Builtin gestartet. Da die Shell-Builtins von Shell zu Shell variieren,<br />
können wir Ihnen leider nicht allgemein gültig sagen, welche Kommandos<br />
shell-intern sind. Zur Lösung des Problems gibt es jedoch das Kommando type (das<br />
ebenfalls ein Shell-Builtin der bash ist 10 ). An type muss lediglich der Name eines<br />
Kommandos oder Programms als Parameter übergeben werden. Daraufhin gibt type<br />
<strong>aus</strong>, ob es sich dabei um ein Shell-Builtin oder um ein Programm handelt, dessen<br />
absoluter Pfad dann <strong>aus</strong>gegeben wird.<br />
type<br />
10 Auch andere Shells, etwa die Z-Shell, bieten diese Funktionalität.<br />
219
7 Die Shell<br />
$ type type<br />
type is a shell builtin<br />
$ type bash<br />
bash is /bin/bash<br />
Listing 7.16 Verwendung des Kommandos type<br />
Es ist zu beachten, dass type – sofern für den übertragenen Parameter sowohl eine<br />
Programmdatei als auch ein Shell-Builtin zur Verfügung stehen – nur <strong>aus</strong>geben wird,<br />
dass ein Builtin vorhanden ist.<br />
$ type kill<br />
kill is a shell builtin<br />
$ ls /bin/kill<br />
/bin/kill<br />
Listing 7.17 kill ist Programm und Builtin<br />
In der Grundfunktionalität identisch, jedoch dank einer Option etwas informa-<br />
tiver ist das Programm which. Dieses Programm ist in einigen Shells als Builtin<br />
vorhanden, existiert aber auch als Programmdatei. which hat die Fähigkeit, über<br />
den Parameter -a alle gefundenen Einträge für einen übergebenen Namen <strong>aus</strong>zugeben.<br />
11 Das bedeutet nichts anderes, als dass, wenn kill als Shell-Builtin vorhanden<br />
ist, sowohl diese Information als auch der Pfad der Binärdatei in /bin <strong>aus</strong>gegeben<br />
wird. Zudem durchsucht which alle in der Variable $PATH angegebenen Verzeichnisse<br />
nach der entsprechenden Datei. Ist beispielsweise which sowohl in /usr/bin<br />
als auch in /bin vorhanden, findet es (sofern $PATH entsprechend gesetzt ist) beide<br />
Dateien.<br />
which<br />
$ which -a which<br />
which: shell built-in command<br />
/usr/bin/which<br />
Listing 7.18 Das Programm which<br />
Alias?<br />
In der Shell kann ein so genanntes Alias angelegt werden. Das ist ein Befehl,<br />
der einen anderen ersetzt – dazu später mehr. type, which und whence (je nach<br />
verwendeter Shell) geben Ihnen auch darüber Auskunft, ob ein Kommando ein<br />
solches Alias ist.<br />
$ type ls<br />
ls is an alias for /bin/ls -aF<br />
$ which -a ls<br />
ls: aliased to /bin/ls -aF<br />
11 Einige type-Implementierungen unterstützen dieses Feature ebenfalls.<br />
220
<strong>Grundlagen</strong> der Shellnutzung 7.7<br />
/bin/ls<br />
$ whence -va ls<br />
ls is an alias for /bin/ls -aF<br />
ls is /bin/ls<br />
Listing 7.19 Alias-Überprüfung<br />
7.7.5 Shell-Aliase<br />
Shell-Aliase bieten eine Möglichkeit zur Kommandosubstitution. Sie erlauben es,<br />
einen neuen Befehlsnamen zu vergeben, der stellvertretend für ein Kommando<br />
oder eine Kommandoreihe steht. Ein Alias wird über das gleichnamige Kommando<br />
alias erstellt und modifiziert. Eine Liste der bereits vorhandenen Alias-Einträge<br />
können Sie ebenfalls <strong>aus</strong>geben lassen.<br />
$ alias<br />
cl="cd ..;ls"<br />
cll="cd ..;ll"<br />
ll="ls -alhoF"<br />
ls="/bin/ls -aF"<br />
Listing 7.20 Aktuelle Alias-Liste anzeigen<br />
Der Vorteil liegt auf der Hand: Wenn Sie beispielsweise ständig das Kommando ls<br />
-laFh <strong>aus</strong>führen und sich dafür das Alias ll erstellen, sparen Sie Zeit und vertippen<br />
sich dabei nicht. Zudem können einem Alias auch Parameter übergeben werden.<br />
Dem Alias ll können also auch ein Dateiname und weitere Parameter für das<br />
ls-Programm übergeben werden.<br />
$ ll ../eil2/buch.ps<br />
-rw------- 1 sw sw 37.7M Feb 20 13:55 ../eil2/buch.ps<br />
Listing 7.21 der Alias ll<br />
Ein Alias erstellen und modifizieren<br />
Ein Alias erstellt man, indem man den neuen Befehlsnamen sowie den Befehl, der<br />
hinter diesem verborgen sein soll, dem alias-Kommando übergibt. Erstellen wir<br />
beispielsweise einmal ein Alias, um den SSH-Login auf einem Host zu automatisieren:<br />
$ alias ssh_milk='export TERM=xterm;ssh swendzel@192.168.0.2'<br />
Listing 7.22 Alias verwenden<br />
221
7 Die Shell<br />
Ein Alias kann modifiziert werden, indem ihm einfach erneut ein (anderer) Befehl zugewiesen<br />
wird.<br />
Ein Alias löschen<br />
Manchmal möchte man eine erstelltes Alias auch wieder löschen. Dies wird ganz<br />
einfach dadurch bewerkstelligt, dass man dem Kommando unalias den entsprechenden<br />
Namen des Alias übergibt.<br />
$ alias system="uname -sr"<br />
$ system<br />
OpenBSD 3.6<br />
$ unalias system<br />
$ system<br />
zsh: command not found: system<br />
Listing 7.23 Das unalias-Kommando<br />
7.7.6 Verzeichniswechsel<br />
Im letzten Kapitel haben Sie bereits die wichtigsten <strong>Grundlagen</strong> kennengelernt,<br />
um sich frei durch den Verzeichnisbaum zu bewegen, sprich: Verzeichnisse zu<br />
wechseln (cd), das aktuelle Arbeitsverzeichnis <strong>aus</strong>zugeben (pwd) und den Inhalt von<br />
Verzeichnissen <strong>aus</strong>zugeben (ls).<br />
Im Folgenden wollen wir uns mit einigen teilweise konfigurationsspezifischen Möglichkeiten<br />
beschäftigen, die Ihnen, was den Verzeichniswechsel anbelangt, die tägliche<br />
Tipperei erleichtern werden. Wahrscheinlich werden Sie auf diese Arbeitsweise,<br />
nachdem Sie sich erst einmal an selbige gewöhnt haben, nicht wieder verzichten<br />
wollen.<br />
Die ersten zwei Tipps (cd . und cd ..) kennen Sie bereits <strong>aus</strong> dem vorherigen<br />
Kapitel – sie werden hier jedoch der Vollständigkeit halber ebenfalls erläutert.<br />
».«<br />
Der Punkt (.) gibt das aktuelle Arbeitsverzeichnis an. Sie benötigen ihn entweder,<br />
wenn Sie in das Verzeichnis wechseln wollen, in dem Sie sich momentan<br />
befinden 12 (optional, wenn Sie auf eine Datei im aktuellen Verzeichnis zugreifen<br />
möchten), aber vor allen Dingen dann, wenn Sie ein Skript oder Programm im<br />
Arbeitsverzeichnis <strong>aus</strong>führen möchten.<br />
12 Nun ... zumindest ist dies möglich – der Sinn solch einer Aktion soll an dieser Stelle nicht<br />
diskutiert werden.<br />
222
<strong>Grundlagen</strong> der Shellnutzung 7.7<br />
$ pwd<br />
/home/user<br />
$ cd .<br />
$ pwd<br />
/home/user<br />
$ ./script.sh<br />
...<br />
Listing 7.24 Ein Skript im aktuellen Verzeichnis <strong>aus</strong>führen<br />
Verwenden Sie hingegen zwei Punkte, so stehen diese stellvertretend für das nächst- »..«<br />
höhere Verzeichnis in der Hierarchie. Dies bedeutet, dass Sie, wenn Sie sich beispielsweise<br />
im Verzeichnis /usr/local/bin befinden, mittels cd .. in das Verzeichnis<br />
/usr/local wechseln können. Diese zwei Punkte können auch durch Slashes mehrfach<br />
verkettet werden.<br />
$ pwd<br />
/usr/local/bin<br />
$ cd ../../include<br />
$ pwd<br />
/usr/include<br />
Listing 7.25 Verzeichnisebene wechseln mit »..«<br />
Geben Sie die zwei Zeichen ˜- beim Verzeichniswechsel an, so wechselt die Shell<br />
anschließend wieder in das Verzeichnis, in dem Sie sich vor dem letzten Verzeichniswechsel<br />
befanden. Hier ein verdeutlichendes Beispiel, denn beim Zuschauen<br />
lernt man ja schließlich am besten:<br />
»˜-«<br />
$ pwd<br />
/usr/local/bin<br />
$ cd /etc<br />
$ pwd<br />
/etc<br />
$ cd ˜-<br />
$ pwd<br />
/usr/local/bin<br />
Listing 7.26 Ins vorherige Verzeichnis zurückkehren<br />
Geben Sie für den Verzeichniswechsel eine Tilde (˜) an, so wechseln Sie in Ihr Heimatverzeichnis.<br />
Verwendet man hingegen die Tilde in Verbindung mit einem Benutzernamen,<br />
so wechselt die Shell in das Heimatverzeichnis des jeweiligen Benutzers,<br />
»˜«<br />
223
7 Die Shell<br />
was natürlich nur funktioniert, wenn man auch die entsprechenden Zugriffsrechte<br />
für diese Aktion hat. 13<br />
$HOME und » «<br />
Wechseln Sie mit der Variable $HOME das Verzeichnis, so kommen Sie – Sie werden<br />
es bereits ahnen – ebenfalls in das eigene Heimatverzeichnis. Die Verwendung der<br />
$HOME-Variable ist allerdings nur möglich, wenn diese auch (korrekt) gesetzt ist, was<br />
bis auf einige Ausnahmesituationen immer der Fall sein sollte.<br />
Derselbe Wechsel in das Heimatverzeichnis ist möglich, indem man dem Kommando<br />
cd einfach gar keinen Parameter übergibt.<br />
$ pwd<br />
/etc<br />
$ cd $HOME; pwd<br />
/home/user<br />
$ cd /etc; cd; pwd<br />
/home/user<br />
Listing 7.27 Trautes Heim<br />
7.7.7 echo<br />
Beschäftigen wir uns nun mit einem grundlegenden Programm, das in den meisten<br />
Shells allerdings auch als Builtin vorhanden ist. Die Rede ist von echo. Dieses<br />
Kommando gibt den ihm übergebenen Text auf der Konsole <strong>aus</strong> und ist besonders<br />
nützlich in der Shellskriptprogrammierung, etwa zum Einsehen von Variablenwerten.<br />
Wir benötigen echo noch sehr oft im weiteren Verlauf des Kapitels, u. a. bei der<br />
Kommandosubstitution und wie bereits erwähnt bei der Shellskriptprogrammierung.<br />
Die Verwendung des Kommandos ist denkbar einfach: Der <strong>aus</strong>zugebende<br />
Text wird als Parameter übergeben und sodann von echo <strong>aus</strong>gegeben.<br />
$ echo "Hallo, Welt\!"<br />
Hallo, Welt!<br />
Listing 7.28 Das Kommando echo<br />
Wie Ihnen vielleicht aufgefallen ist, gibt es hierbei doch etwas zu beachten: Einige<br />
Sonderzeichen, wie im obigen Beispiel das Ausrufezeichen, müssen durch<br />
Escape-Sequenzen eingeleitet werden, da diese Zeichen ansonsten andere Aktionen<br />
einleiten. Später werden Sie einige solcher Sonderzeichen kennenlernen, etwa das<br />
Dollarzeichen ($), das für Variablen Verwendung findet.<br />
13 Dazu muss sowohl das Lese- als auch das Ausführrecht gegeben sein, also (mindestens) r-x.<br />
224
<strong>Grundlagen</strong> der Shellnutzung 7.7<br />
Zunächst einmal werden wir solche Probleme durch Hochkommata umgehen. Alles,<br />
was Sie in Hochkommata stellen, wird von der Shell nicht weiter interpretiert, echo<br />
gibt es dann einfach <strong>aus</strong>.<br />
$ echo 'Hallo, Welt!'<br />
Hallo, Welt!<br />
Listing 7.29 echo in Verwendung mit Hochkommas<br />
7.7.8 Shellvariablen<br />
Ein wichtiges Werkzeug im Umgang mit der Shell, insbesondere bei der Skriptprogrammierung,<br />
sind Variablen. Einer Variablen können Sie einen Wert zuweisen, auf<br />
den Sie später wieder (und beliebig oft) zugreifen können. Solch ein zugewiesener<br />
Wert kann eine Zahl, die Ausgabe eines ganzen Programms oder ein String, also<br />
eine Zeichenkette wie »Hallo, Welt!«, sein.<br />
Variablen werden über einen wählbaren Namen vergeben. Nehmen wir einmal an,<br />
der Name eines glorreichen Getiers, nämlich Felix, solle in einer Variable gespeichert<br />
werden. Es wäre beispielsweise sinnvoll, dieser Variable den Namen »KATZE«<br />
oder »KATZENNAME« zu geben. In der Regel schreibt man Shellvariablen übrigens<br />
in Großbuchstaben; dies ist jedoch nicht zwingend notwendig! Die Zuweisung erfolgt<br />
in der Familie der Bourne-Shell 14 durch ein Gleichheitszeichen:<br />
Zuweisung von<br />
Werten<br />
$ KATZE=Felix<br />
Listing 7.30 Der Variable KATZE den Wert »Felix« zuweisen<br />
Durch eine erneute Zuweisung eines Wertes wird der alte Variablenwert überschrieben.<br />
Um den Wert einer Variablen einzusehen, kann unter anderem echo verwendet<br />
werden. Die Shell übergibt echo in diesem Fall den Inhalt der angegebenen Variablen,<br />
so dass echo nicht mitbekommt, dass es einen Variableninhalt <strong>aus</strong>gibt. Die<br />
beiden folgenden Befehle bewirken folglich dasselbe:<br />
Abfrage von Werten<br />
$ echo Felix<br />
Felix<br />
$ echo $KATZE<br />
Felix<br />
Listing 7.31 echo mit und ohne Variable<br />
14 In der Familie der C-Shell muss hierzu das Shell-Builtin set verwendet werden.<br />
225
7 Die Shell<br />
Beachten Sie, dass beim Zugriff auf eine Variable ein Dollarzeichen ($) vor den<br />
Namen der Variablen gesetzt werden muss, sonst interpretiert die Shell diesen als<br />
String:<br />
$ echo KATZE<br />
KATZE<br />
Listing 7.32 Fehler: Dollarzeichen vergessen<br />
Löschen von Variablen<br />
Um eine Variable wieder zu löschen, muss deren Name nur dem unset-Kommando<br />
übergeben werden.<br />
$ echo $KATZE<br />
Felix<br />
$ unset KATZE<br />
$ echo $KATZE<br />
$<br />
Listing 7.33 Das Kommando unset<br />
Variablen in Text einbetten und <strong>aus</strong>geben<br />
Um eine Variable in den Text einer Ausgabe (oder in den Wert einer anderen<br />
Variablen) einzubauen, gibt es zwei Herangehensweisen.<br />
Die erste Möglichkeit besteht darin, die Variable, wie bereits mit echo gezeigt, in<br />
der Form $NAME zuverwenden,wasfastimmerproblemlosfunktioniert.<br />
$ echo "Herzlich willkommen, $KATZE\!"<br />
Herzlich willkommen, Felix!<br />
Listing 7.34 Variable im Text<br />
Gehen wir nun davon <strong>aus</strong>, dass wir neben der Variable KATZE noch eine zweite<br />
Variable mit dem Namen KATZE2 benutzen. Für den Fall, dass Sie den Wert von<br />
KATZE und direkt danach eine »2« <strong>aus</strong>geben möchten, können Sie nun nicht mehr<br />
die soeben besprochene Variante verwenden, sondern müssen den Variablennamen<br />
in geschweifte Klammern setzen. Das ist nötig, um dessen Anfang und Ende genau<br />
zu markieren.<br />
$ KATZE2="Mauzi"<br />
$ echo "Herzlich willkommen, $KATZE2\!"<br />
Herzlich willkommen, Mauzi!<br />
$ echo "Herzlich willkommen, ${KATZE}2\!"<br />
Herzlich willkommen, Felix2!<br />
Listing 7.35 Variable im Text<br />
226
<strong>Grundlagen</strong> der Shellnutzung 7.7<br />
Mehr zur Einbettung von Variablenwerten in Text oder andere Variablenwerte<br />
erfahren Sie in Abschnitt 7.7.9, »Kommandosubstitution«.<br />
Vorhandene Variablen anzeigen lassen<br />
Alle aktuell vorhandenen Variablen sowie die Werte, die diesen zugewiesen wurden,<br />
können Sie mittels des set-Kommandos einsehen. Dabei werden sowohl lokale<br />
als auch globale Variablen angezeigt (mehr dazu im nächsten Absatz). 15<br />
$ set<br />
...<br />
XCURSOR_SIZE=""<br />
XCURSOR_THEME=""<br />
XYRIA=/home/swendzel/projekte/xyria_<br />
ZSH_NAME=zsh<br />
ZSH_VERSION=4.2.1<br />
_=set<br />
aliases<br />
...<br />
Listing 7.36 set, <strong>aus</strong>geführt in der Z-Shell<br />
Variablen einlesen<br />
Selbstverständlich kann man auch den Wert einer Variablen von der Tastatur einlesen<br />
lassen. Dies wird über das Builtin read bewerkstelligt. Man übergibt read den<br />
Namen der gewünschten Variablen (ohne das Dollarzeichen davor). Die Eingabe<br />
wird durch die Eingabetaste beendet.<br />
$ read Name<br />
Felix<br />
$ echo $Name<br />
Felix<br />
Listing 7.37 read verwenden<br />
Einige Shells unterstützten weitere Parameter für read. So kann etwa mit dem Parameter -n<br />
ANZAHL die Anzahl der einzulesenden Zeichen angegeben werden. Mit -s wird hingegen<br />
die Eingabe des Benutzers nicht angezeigt. Mit read -s -n 8 pw würde also ein maximal<br />
achtstelliger Wert in die Variable »pw« eingelesen und die eingegebenen Zeichen nicht<br />
angezeigt.<br />
15 In einigen Shells gibt set noch zusätzliche Informationen, etwa Shellfunktionen, <strong>aus</strong>.<br />
227
7 Die Shell<br />
Schreibgeschützte Variablen<br />
Variablen können mit einem Schreibschutz versehen werden. Damit lässt sich sicherstellen,<br />
dass ihr Wert nicht <strong>aus</strong> Versehen wieder verändert wird. Hierzu wird<br />
dem readonly-Kommando einfach der Name der jeweiligen Variablen übergeben.<br />
Übergeben Sie readonly keinen Parameter, so erhalten Sie eine Liste aller derzeit<br />
schreibgeschützten Variablen.<br />
Globale und lokale Variablen<br />
Eben sprachen wir bereits an, dass es sowohl lokale als auch globale Variablen gibt.<br />
Wir wollen Ihnen selbstverständlich nicht den Unterschied zwischen diesen beiden<br />
Variablenarten vorenthalten.<br />
Eine globale Variable wird im Gegensatz zu einer lokalen an Unterprogramme<br />
übergeben. Viele Programme nutzen dieses Feature, etwa das Programm BitchX,<br />
ein freier IRC-Client. Dieser greift für die Konfiguration der IRC-Verbindung auf<br />
globale Variablen zurück:<br />
IRCNAME="Steffen W"<br />
IRCNICK=cdp_xe<br />
IRCPORT=6667<br />
IRCSERVER=milk.sun<br />
Listing 7.38 Globale Variablen für BitchX<br />
Würden Sie nun das Programm bitchx <strong>aus</strong> einer Shell mit diesen globalen Variablen<br />
starten, so würde es deren Werte verwenden.<br />
export<br />
Globale Variablen<br />
erzeugen<br />
Um sich eine Liste der globalen Variablen, die aktuell in der Shell geladen sind,<br />
anzeigen zu lassen, müssen Sie nur das Kommando export aufrufen.<br />
Mittels export können Sie übrigens auch globale Variablen erstellen. Sie gehen<br />
dabei wie bei der Erstellung von lokalen Variablen vor, nur dass Sie den Erzeugungsbefehl<br />
dem Kommando export übergeben.<br />
$ export KATZE=Felix<br />
$ export | grep KATZE<br />
KATZE=Felix<br />
Listing 7.39 Erzeugen einer globalen Variablen<br />
Auch globale Variablen können mit dem Kommando unset wieder gelöscht werden.<br />
228
<strong>Grundlagen</strong> der Shellnutzung 7.7<br />
Die wichtigsten globalen Variablen<br />
Es gibt einige globale Variable, die für die Nutzung des Unix-Betriebssystems äußerst<br />
wichtig sind und daher bekannt sein sollten. Wir haben sie sowie ihre Bedeutung<br />
in einer kleinen Tabelle zusammengefasst. Einige spezielle Variable wie $?<br />
werden wir im Verlauf des Kapitels (nämlich bei der Shellskriptprogrammierung)<br />
noch genauer besprechen.<br />
Variable<br />
$HOME<br />
$LOGNAME und teilweise<br />
auch $USER<br />
$PATH<br />
$PS1 bis $PS4<br />
$RPS1<br />
$TERM<br />
Bedeutung<br />
Heimatverzeichnis des Benutzers<br />
Loginname des Benutzers<br />
Liste von Verzeichnissen, die nach einer relativ angegebenen,<br />
<strong>aus</strong>führbaren Datei durchsucht werden sollen (siehe Seite<br />
217).<br />
Kommandozeilen-Prompt (detailliert beschrieben im folgenden<br />
Abschnitt)<br />
Prompt am rechten Konsolenrand in der Z-Shell<br />
verwendetes Terminal, z. B. »xterm-color«<br />
$0 Name des aktuellen Prozesses<br />
$$ aktuelle Prozess-ID<br />
$n der einem Skript oder einer Skriptfunktion übergebene Parameter<br />
Nummer »n«<br />
$# Gesamtzahl der an eine Funktion oder ein Skript übergebenen<br />
Parameter<br />
$? Rückgabewert des zuletzt in dieser Shell beendeten Prozesses<br />
$* und $@ alle dem Skript oder einer Funktion übergebenen Parameter<br />
$! Prozess-ID des letzten Hintergrundprozesses<br />
$_<br />
Tabelle 7.1 Wichtige globale Variablen<br />
letzter Parameter des zuletzt <strong>aus</strong>geführten Befehls<br />
Der Shell-Prompt<br />
Eine Shell verfügt über einen Standardprompt und einige Nebenprompts. Dochwas<br />
ist eigentlich solch ein Prompt? Im Prinzip ist ein Prompt eine Ausgabe von Textzeichen,<br />
die Sie zur Eingabe eines Kommandos auffordert. Je nach verwendeter Shell<br />
und der persönlichen Konfiguration der entsprechenden Variablen kann solch ein<br />
Prompt ganz unterschiedlich <strong>aus</strong>sehen. Hier im Buch haben wir meistens user$ und<br />
$ als Benutzerprompt, sowie root# und # als Prompt des Superusers verwendet,<br />
was typisch für eine Unix-Shell ist.<br />
229
7 Die Shell<br />
Jeder Prompt wird über eine bestimmte Variable festgelegt. Der primäre Prompt<br />
nennt sich PS1, diesen sehen Sie standardmäßig. Versuchen Sie einmal, diesen<br />
Prompt zu löschen mit<br />
$ unset PS1<br />
Listing 7.40<br />
Sie werden feststellen, dass nun jegliche Eingabeaufforderung fehlt. Sie können<br />
allerdings nach wie vor Befehle <strong>aus</strong>führen. Um das Prompt wiederherzustellen,<br />
können Sie die Variable PS1 wieder global setzen – eine passende Übung zur frisch<br />
erlernten Variablenbenutzung. 16 Mit dem Prompt lassen sich allerdings noch einige<br />
andere Spielereien anstellen. Beispielsweise können Sie, um sich die Arbeit zu<br />
erleichtern, das aktuelle Arbeitsverzeichnis oder den Benutzernamen, mit dem Sie<br />
derzeit arbeiten, anzeigen lassen.<br />
Dazu müssen Sie sogenannte Escape-Sequenzen in die PS1-Variable einbauen. Eine<br />
Escape-Sequenz ist einfach eine Buchstabenfolge (oder ein einzelner Buchstabe),<br />
die durch einen vorangestellten Backslash auf eine bestimmte Art von der Shell<br />
interpretiert wird. Die Escape-Sequenzen für die Prompt-Konfiguration sind allerdings<br />
von Shell zu Shell verschieden, weshalb wir uns im Folgenden auf die bash<br />
konzentrieren.<br />
Sequenz<br />
Wirkung<br />
\a Ausgabe eines Tons im PC-Speaker (nervt)<br />
\d Zeigt das Datum an.<br />
\e Escape-Zeichen<br />
\h der Hostname (z. B. ’rechner’)<br />
\H FQDN-Hostname (z. B. ’rechner.netzwerk.edu’)<br />
\j Anzahl der Hintergrundprozesse<br />
\l Name des Terminals<br />
\n neue Zeile (Prompts können tatsächlich über mehrere Zeilen verteilt<br />
werden)<br />
\r Carriage-Return<br />
\s Name der Shell<br />
\t Zeit im 24-Stunden-Format<br />
\T Zeit im 12-Stunden-Format<br />
Tabelle 7.2 Escape-Sequenzen<br />
16 Hier eine mögliche Lösung: export PS1="\$ "<br />
230
<strong>Grundlagen</strong> der Shellnutzung 7.7<br />
Sequenz<br />
\@<br />
Wirkung<br />
Zeit im AM/PM-Format<br />
\u Name des Benutzers<br />
\v Version der bash<br />
\V \v, jedoch mit Patch-Level<br />
\w Gibt das Arbeitsverzeichnis an.<br />
\W Gibt nur das aktuelle Arbeitsverzeichnis ohne höhere Ebenen der<br />
Verzeichnishierarchie an.<br />
\# Anzahl der bereits aufgerufenen Kommandos während der Shell-<br />
Session des Terminals<br />
\$ Ist man als normaler Benutzer eingeloggt, so erscheint ein Dollarzeichen,<br />
root bekommt eine Raute (#) zu sehen.<br />
\\ ein Backslash<br />
Tabelle 7.2 Escape-Sequenzen (Forts.)<br />
Es existieren noch weitere Escape-Sequenzen, beispielsweise zur Festsetzung der<br />
farblichen Hervorhebung. Diese werden im Rahmen dieses Buches jedoch nicht<br />
behandelt, da sie nicht auf allen Terminals funktionieren.<br />
Für besonders<br />
Interessierte ...<br />
Einige Distributionen und sehr viele Benutzer verwenden die Variante Benutzer@Host<br />
Verzeichnis$, die ein an dieser Stelle besonders gut passendes Beispiel<br />
zur Nutzung von Escape-Sequenzen darstellt.<br />
user$ PS1="\u@\h \w\$"<br />
swendzel@deb-sid /usr$ ls<br />
...<br />
Listing 7.41 Setzung des bash-Prompts mit Escape-Sequenzen<br />
Neben dem Standard-Prompt $PS1 gibt es noch weitere Prompts:<br />
Zum einen sind dies die Eingabeaufforderungen zur Vervollständigung von Shellanweisungen<br />
(hiermit sind beispielsweise if-Anweisungen gemeint, die Sie in der<br />
Shellskriptprogrammierung kennenlernen werden). Sie werden (je nach Shell) mit<br />
$PS2 ... $PS4 bezeichnet. Da diese Prompts fast nie verwendet werden, behalten die<br />
meisten Benutzer ihre Standardkonfiguration bei.<br />
Außerdem gibt es in der Z-Shell den $RPS1-Prompt. Dieser Prompt ist ein rechtsseitiger<br />
Prompt, den man beispielsweise sehr gut nutzen kann, um sich Uhrzeit und<br />
Datum <strong>aus</strong>geben zu lassen.<br />
Weitere Prompts<br />
$PS2..4<br />
$RPS1<br />
231
7 Die Shell<br />
7.7.9 Kommandosubstitution<br />
Die Kommandosubstitution bietet Ihnen – besonders in der Shellskriptprogrammierung<br />
– die Möglichkeit, durch etwas Einfaches etwas sehr Nützliches zu erreichen.<br />
Sie erlaubt es Ihnen nämlich, die Ausgaben eines Programms direkt in einer Variable<br />
zu speichern oder als Parameter für andere Programme zu verwenden.<br />
Erst einmal ganz einfach ...<br />
Für diese Kommandosubstitution werden spezifische Einbettungszeichen verwendet,<br />
die sogenannten Backticks 17 . Alles, was Sie innerhalb dieser Zeichen schreiben,<br />
wird von der Shell als Befehl interpretiert. Dessen Ausgabe wird für alles Weitere,<br />
also etwa für die Zuweisung an eine Variable, verwendet.<br />
Schauen wir uns die Anwendung der Backticks einmal an. Im folgenden Beispiel<br />
weisen wir der Variablen $OUTPUT die Ausgabe des ls-Befehls zu.<br />
user$ OUTPUT=`ls`<br />
user$ echo $OUTPUT<br />
CVS<br />
Makefile<br />
TODO<br />
ZEITPLAN<br />
anhg_komref.aux<br />
anhg_komref.tex<br />
buch.dvi<br />
buch.idx<br />
buch.ilg<br />
buch.ind<br />
...<br />
Listing 7.42 Kommandosubstitution<br />
Wie Sie sehen, kann die Variable sofort weiterverwendet werden, indem man sie<br />
wie im Beispiel einem Programm wie echo übergibt. Vielleicht fragen Sie sich<br />
bereits, ob man eine Kommandosubstitution nicht auch direkt ohne Zwischenspeicherung<br />
in einer Variable an einen anderen Befehl übergeben kann. Mit dieser<br />
Vermutung haben Sie Recht, wie das folgende Listing zeigt.<br />
Das ls-Programm (siehe Anhang B, »Kommandoreferenz«, auf Seite 1220) soll uns<br />
Detailinformationen zu den einzelnen Dateien des Verzeichnisses <strong>aus</strong>geben. Diese<br />
übergeben wir jedoch über eine Kommandosubstitution. Dies ist nicht sonderlich<br />
17 Auf einer PC-Tastatur drückt man für diese Zeichen Shift und ‘ (Backtick, das ist die Taste<br />
neben ?\)<br />
232
<strong>Grundlagen</strong> der Shellnutzung 7.7<br />
sinnvoll, verdeutlicht aber sehr gut die Funktionsweise der direkten Kommandosubstitution.<br />
user$ ls -l `ls`<br />
-rw------- 1 cdp_xe cdp_xe 707 Mar 15 15:45 Makefile<br />
-rw------- 1 cdp_xe cdp_xe 289 Feb 20 14:10 TODO<br />
-rw------- 1 cdp_xe cdp_xe 1809 Mar 17 14:16 ZEITPLAN<br />
-rw------- 1 cdp_xe cdp_xe 2076 Mar 17 19:23 anhgkf.tex<br />
-rw------- 1 cdp_xe cdp_xe 227844 Mar 17 19:24 buch.dvi<br />
-rw------- 1 cdp_xe cdp_xe 2126 Mar 17 19:24 buch.idx<br />
-rw------- 1 cdp_xe cdp_xe 413 Mar 17 19:24 buch.ilg<br />
...<br />
Listing 7.43 Direkte Kommandosubstitution<br />
Dieser Aufruf ist nicht mit einem bloßen Aufruf von ls -l gleichzusetzen, da hier<br />
Verzeichnisdateien die Ausgabe eines gesamten Verzeichnisinhalts bewirken. Solche<br />
feinen Unterschiede sollten bei der Kommandosubstitution generell bedacht<br />
werden. Da Sie jedoch schon einige Erfahrung mit Shells haben müssen, um überhaupt<br />
an solche Unterschiede zu denken, hilft nur eines: Spielen Sie mit der Shell!<br />
Beachten Sie, dass die Kommandosubstitution nur die Standard<strong>aus</strong>gabe eines Befehls liefert<br />
– Fehlermeldungen werden über die Standardfehler<strong>aus</strong>gabe geliefert und bleiben daher<br />
unentdeckt!<br />
Diese Kommandosubstitution ist leider nicht immer ohne Weiteres möglich. Dies<br />
gilt auch für die Verwendung von Variablen. Es gibt hier feine, aber entscheidende<br />
Unterschiede. Es gibt nämlich verschiedene Arten, wie Text oder Anweisungen<br />
eingeschlossen werden können: in Hochkommata, Backticks oder Anführungszeichen.<br />
Jede dieser drei Möglichkeiten hat andere Folgen. Nehmen wir im Folgenden<br />
einmal an, der Variablen $VAR wurde der Text »hallo« zugewiesen.<br />
In Anführungszeichen werden sowohl Variablenwerte als auch Kommandosubstitutionen<br />
umgesetzt.<br />
Anführungszeichen<br />
$ echo "$VAR `pwd`"<br />
hallo /home/cdp_xe/books/kompendium<br />
Listing 7.44 Anführungszeichen<br />
In Backticks werden Kommandosubstitutionen eingeschlossen. Variablenwerte werden<br />
hierbei als Kommando interpretiert.<br />
Backticks<br />
233
7 Die Shell<br />
$ echo `$VAR` `pwd`<br />
zsh: command not found: hallo<br />
/home/cdp_xe/books/kompendium<br />
Listing 7.45 Backticks<br />
Als Alternative zu den Backticks kann auch die Notation $( Kommando ) genutzt<br />
werden.<br />
Hochkommata<br />
In Hochkommata sind sowohl Variablenangaben als auch explizit in Backticks angegebene<br />
Kommandosubstitutionen wirkungslos.<br />
$ echo '$VAR `pwd`'<br />
$VAR `pwd`<br />
Listing 7.46 Hochkommata<br />
7.8 Ein- und Ausgabeumlenkung<br />
Normalerweise funktioniert das Arbeiten mit einem Unix-Prozess folgendermaßen:<br />
Sie geben die gewünschten Befehle über die Tastatur ein, und der Prozess führt sie<br />
<strong>aus</strong>. Dabei gibt der Prozess die Ergebnisse der Arbeit auf dem Bildschirm <strong>aus</strong>. Mit<br />
der Ein- und Ausgabeumlenkung, einem mächtigen Werkzeug in der Shell, lässt<br />
sich dies ändern.<br />
Jedem Prozess sind unter Unix standardmäßig drei Deskriptoren zugewiesen. Hierüber<br />
können Ein- und Ausgabe des Programms erfolgen. Ein Deskriptor stellt für<br />
einProgrammeineMöglichkeitdar,zulesenundzuschreiben.Obdabeiineine<br />
Datei oder auf den Bildschirm geschrieben wird, ist egal. 18 Deskriptoren sind für<br />
ein Programm vollständig transparent.<br />
Doch nun zurück zu den erwähnten drei Standarddeskriptoren. Dies sind:<br />
<br />
<br />
<br />
Standardeingabe (0, STDIN)<br />
Standard<strong>aus</strong>gabe (1, STDOUT)<br />
Standardfehler<strong>aus</strong>gabe (2, STDERR)<br />
Die Zahlenwerte in den Klammern sind die dem Deskriptor zugewiesenen Nummern,<br />
mit denen Sie in der Shell arbeiten können. Tippen Sie also z. B. »1« für die<br />
Standard<strong>aus</strong>gabe, die mit STDOUT bezeichnet wird.<br />
18 Eigentlich kann man nicht sagen, dass »ein Programm auf den Bildschirm schreibt«. Das<br />
Programm schreibt die Daten über Deskriptoren, den Rest erledigt der Kernel (s. Kapitel 5).<br />
234
Ein- und Ausgabeumlenkung 7.8<br />
7.8.1 Ausgabeumlenkung<br />
Fast jedes Programm gibt Daten auf dem Monitor <strong>aus</strong>. Diese können, wie bereits<br />
erwähnt, umgeleitet werden. Doch wohin? Unter Unix-Systemen erfolgt die Umleitung<br />
in Dateien. 19 Dadurch kann beispielsweise die Ausgabe eines Programms<br />
protokolliert oder später mit einem Editor bearbeitet werden.<br />
Nehmen wir einmal an, die Ausgabe des ls-Programms solle in die Datei list umgeleitet<br />
werden. Dazu muss lediglich folgender Befehl <strong>aus</strong>geführt werden:<br />
user$ ls 1> list<br />
Listing 7.47 Eine Ausgabeumlenkung<br />
Die »1« vor dem Größer-als-Zeichen dient dabei zur Angabe des Deskriptors, hier<br />
also STDOUT. Das Größer-als-Zeichen selbst wird von der Shell als Befehl zur Umlenkung<br />
der Ausgabe interpretiert. Mit cat list können Sie sich die Ausgabe des<br />
ls-Programmes ansehen.<br />
Eine Ausgabeumlenkung erfolgt durch ein Größer-als-Zeichen (>), wobei die Nummer des<br />
Deskriptors (entweder »1« für STDOUT oder »2« für STDERR) vorangestellt werden sollte.<br />
Wird keine Nummer vorangestellt, wird automatisch die Standard<strong>aus</strong>gabe (STDOUT)<br />
verwendet.<br />
7.8.2 Fehlerumlenkung<br />
Gäbe es im obigen Beispiel einen Fehler, etwa weil die Zugriffsberechtigung das<br />
Anzeigen des Dateiinhalts eines bestimmten Verzeichnisses verböte, so erschiene<br />
auf dem Bildschirm eine Fehlermeldung. Doch auch diese kann umgelenkt werden.<br />
user$ ls /root<br />
ls: root: Permission denied<br />
user$ ls /root 2>log<br />
user$ cat log<br />
ls: root: Permission denied<br />
Listing 7.48 Eine Umlenkung der Fehler<strong>aus</strong>gabe<br />
Wie Sie sehen, ist auch die Umlenkung der Fehler<strong>aus</strong>gabe sehr einfach zu bewerkstelligen.<br />
Ein spezieller Trick zur Unterdrückung von Fehlermeldungen bietet sich<br />
19 Später werden Sie Pipes kennenlernen, die ähnliche Möglichkeiten wie die Ein- und Ausgabeumlenkung<br />
bieten.<br />
235
7 Die Shell<br />
übrigens durch die Umlenkung der Fehler<strong>aus</strong>gabe auf den »Mülleimer« /dev/null.<br />
Diese Technik ist besonders dann hilfreich, wenn man als normaler Benutzer eine<br />
Dateisuche mit find im ganzen Dateisystem startet – der Zugriff auf viele Verzeichnisse<br />
wird Ihnen dabei nicht gestattet, und der Bildschirm wird mit Fehlermeldungen<br />
übersät sein. Durch die Umlenkung der Fehler<strong>aus</strong>gabe nach /dev/null<br />
kann Ihnen dies erspart bleiben. Parallel dazu können Sie – denn auch dies ist<br />
möglich – die Standard<strong>aus</strong>gabe in eine Datei umlenken, um die Suchergebnisse zu<br />
protokollieren:<br />
user$ find / -name Dateiname >Ergebnisse 2>/dev/null<br />
Listing 7.49 Unterdrückung von Fehlern<br />
7.8.3 Die Ausgabe an eine Umlenkung anhängen<br />
Manchmal möchte man sowohl die Standard<strong>aus</strong>gabe als auch die Fehler<strong>aus</strong>gabe<br />
protokollieren – und dies in der korrekten Reihenfolge. In diesem Fall bietet die<br />
Unix-Shell noch ein weiteres Feature, nämlich das Anhängen einer Umlenkung an<br />
eine andere.<br />
Dabei wird hinter die Anweisung zur Ausgabeumlenkung ein kaufmännisches Und<br />
(&) gesetzt, dem unmittelbar, also ohne Leerzeichen, die Nummer des Deskriptors<br />
folgen muss, an dessen Umlenkung die Ausgabe angehängt werden soll, etwa 2>&1.<br />
user$ ls /home /root >log 2>&1<br />
user$ cat log<br />
ls: root: Permission denied<br />
/home:<br />
Makefile<br />
backup<br />
cdp_xe<br />
/root:<br />
Listing 7.50 Anhängen einer Umlenkung<br />
7.8.4 Eine Ausgabe in eine bestehende Datei umlenken<br />
Manchmal kommt es vor, dass eine Ausgabe in eine Datei umgelenkt werden soll, in<br />
der sich bereits ein Inhalt befindet, der jedoch nicht überschrieben werden soll. Um<br />
dieses Problem zu lösen, hängen Sie die Ausgabe an den bestehenden Dateiinhalt<br />
an. Dies wird mit zwei Größer-als-Zeichen realisiert:<br />
236
Ein- und Ausgabeumlenkung 7.8<br />
$ uname -a >log<br />
$ who am i >>log<br />
$ cat log<br />
OpenBSD eygo.sun 3.6 EYGO#0 i386<br />
cdp_xe ttyp7 Mar 19 14:30<br />
Listing 7.51 Text anhängen<br />
7.8.5 Eingabeumlenkung<br />
In den meisten Fällen gibt man Befehle und Eingaben für Prozesse über die Tastatur<br />
ein – dies lässt sich ändern. Falls Sie sich fragen, was Ihnen dieses Feature überhaupt<br />
bringen soll, sei gesagt, dass der richtige Nutzwert sich erst in der Programmierung<br />
von Shellskripten zeigt. Aber auch im Alltag kann die Eingabeumlenkung hilfreich<br />
sein, hierzu ein kleines Beispiel:<br />
Ein Programm soll jeden Tag zwanzigmal <strong>aus</strong>geführt werden. Das Programm benötigt<br />
dabei verschiedene Eingaben, nämlich den Namen des Anwenders und dessen<br />
User-ID. Da Sie diese Daten nicht jeden Tag zwanzigmal erneut eingeben möchten,<br />
können Sie sich durch eine Eingabeumlenkung und die somit vorgenommene Automatisierung<br />
dieser Eingabe Arbeit ersparen. Zur Demonstration des Beispiels soll<br />
ein kleines Shellskript dienen, das eben genau diese Eingaben, also den Benutzernamen<br />
und die User-ID, abfragt (gute Programme bekommen dies natürlich allein<br />
her<strong>aus</strong>).<br />
$ ./tool.sh<br />
Benutzername: Steffen Wendzel<br />
User-ID: 1000<br />
Danke für Ihre Anmeldung, Steffen Wendzel (1000).<br />
Listing 7.52 Ein Aufruf von tool.sh<br />
Nun lenken wir die benötigten Eingabedaten einfach in eine Datei um. Dabei sollten<br />
Sie wissen, dass die Zeichensequenz \n dem Drücken der Eingabetaste entspricht<br />
und in der Ausgabe eine neue Zeile einleitet. Durch den Parameter -e werden die<br />
Escape-Sequenzen entsprechend interpretiert. Bei der Z-Shell kann dieser Parameter<br />
aber auch weggelassen werden.<br />
$ echo -e "Steffen Wendzel\n1000\n" > Eingabe<br />
$ cat Eingabe<br />
Steffen Wendzel<br />
1000<br />
$<br />
Listing 7.53 Erstellen einer Datei mit den typischen Eingaben<br />
237
7 Die Shell<br />
Die Eingabeumlenkung funktioniert anders als die Ausgabeumlenkung mit einem<br />
Kleiner-als-Zeichen (
Pipes 7.9<br />
apropos<br />
ar<br />
...<br />
Listing 7.55 Pipe zwischen ls und more<br />
Probieren Sie es einmal <strong>aus</strong> – eine Seite weiter »blättern« Sie durch Drücken der<br />
Leertaste.<br />
Es ist übrigens auch möglich, mehrere Pipes in einem Befehl zu verwenden. Dies<br />
könnte dann beispielsweise so <strong>aus</strong>sehen:<br />
Mehrere Pipes<br />
user$ ls -l | awk '{ print $5 }' | sort | uniq<br />
Listing 7.56 Mehrere Pipes<br />
Die Standardfehler<strong>aus</strong>gabe (STDERR) wird nicht über Pipes weitergeleitet. Dies kann<br />
man jedoch umgehen, indem man STDERR an STDOUT anhängt: ProgrammA 2>&1 |<br />
ProgrammB<br />
7.9.1 Duplizieren der Ausgabe mit tee<br />
Manchmal kommt es vor, dass man die Ausgabe eines Programms sowohl in eine<br />
Datei umleiten als auch gleichzeitig auf dem Bildschirm <strong>aus</strong>geben möchte. Hier<br />
schafft das Programm tee Abhilfe. tee gibt die ihm eingegebene bzw. eingeleitete<br />
Ausgabe auf dem Bildschirm und in einer Datei <strong>aus</strong>.<br />
user$ ls | tee log.txt<br />
CVS<br />
Makefile<br />
TODO<br />
ZEITPLAN<br />
anhg_komref.tex<br />
...<br />
Listing 7.57 Pipes mit tee<br />
7.9.2 Named Pipes (FIFOs)<br />
Named Pipes (sogenannte FIFOs (First In First Out)) erweitern die Fähigkeiten einer<br />
Pipe. Eine FIFO muss zunächst als Datei im Dateisystem erzeugt werden. Dies wird<br />
mit dem Programm mkfifo bewerkstelligt. Der Vorteil gegenüber einer Pipe ist<br />
dabei, dass mehrere Prozesse diese FIFO verwenden können.<br />
239
7 Die Shell<br />
FIFOs arbeiten nach dem First-In-First-Out-Prinzip. Das bedeutet: Die Daten, die zuerst<br />
in eine FIFO geschrieben werden, werden auch als Erste wieder vom lesenden<br />
Prozess empfangen.<br />
Das folgende Listing demonstriert diese Möglichkeit anhand einer Endlosschleife.<br />
Zunächst wird mit dem Programm mkfifo eine FIFO angelegt. Das tee-Programm<br />
lassen wir in die FIFO hineinschreiben, aber gleichzeitig durch Eingabeumlenkung<br />
<strong>aus</strong> ihr lesen. Das bedeutet, dass das Gelesene sofort wieder hineingeschrieben<br />
wird. Sobald also Daten in die FIFO geschrieben werden, liest tee diese so lange<br />
<strong>aus</strong> und schreibt sie so lange wieder in die FIFO hinein, bis der Wärmetod des<br />
Universums eintritt, der Strom <strong>aus</strong>fällt oder der Rechner abfackelt.<br />
Doch um den Prozess anzustoßen, schreiben wir einen String, nämlich »Endlosschleife«<br />
in die FIFO hinein. Es ist wichtig, dass auch dieser Prozess im Hintergrund<br />
gestartet wird, denn irgendwann soll diese Ausgabe ja dann doch gestoppt werden,<br />
um nicht das System abzuschießen.<br />
Nachdem eine Sekunde durch sleep (siehe Seite 1231) gewartet wurde, wird das<br />
Programm tee durch den Aufruf des pkill-Programms beendet. pkill beendet alle<br />
Prozesse, in deren Namen der angegebene Ausdruck vorkommt. Führen Sie diesen<br />
Test auf keinen Fall als Superuser auf einem Multiuser-System durch und bedenken<br />
Sie, dass alle anderen tee-Prozesse, für die der Benutzer die Beendigungsberechtigung<br />
besitzt, ebenfalls beendet werden!<br />
user$ mkfifo fifo<br />
user$ ls -l fifo<br />
prw------- 1 cdp_xe cdp_xe 0 Mar 22 19:44 fifo<br />
user$ tee fifo < fifo&<br />
[1] 2702<br />
user$ echo "Endlosschleife" > fifo & ; \<br />
> sleep 1; pkill tee<br />
[1] 18277<br />
Endlosschleife<br />
Endlosschleife<br />
Endlosschleife<br />
Endlosschleife<br />
...<br />
...<br />
Endlosschleife<br />
Endlosschleife<br />
[1] + terminated tee fifo < fifo<br />
Listing 7.58 Verwendung einer FIFO in der Shell<br />
240
Subshells und Kommandogruppen 7.10<br />
Wie Ihnen vielleicht aufgefallen ist, wird eine Pipe beim »langen« Listing mit ls<br />
mit einem p gekennzeichnet. Dieses p steht für (Named) Pipe und zeigt Ihnen an,<br />
dass es sich um keine reguläre Datei handelt. Versuchen Sie einmal, sich mit dem<br />
Programm file den Typ der Datei anzeigen zu lassen.<br />
7.10 Subshells und Kommandogruppen<br />
In der Shell können nicht nur einfach Kommandos aneinandergereiht werden. Es<br />
gibt neben den bloßen (bedingten) Aneinanderreihungen von Kommandos nämlich<br />
noch zwei weitere Möglichkeiten, dies zu organisieren.<br />
Die erste Möglichkeit ist das Bilden einer Prozessgruppe. Diese umfasst dabei die<br />
aneinandergereihten Prozesse. Dies bietet dem Anwender neue Möglichkeiten, etwa<br />
die Ausgabeumlenkung für die gesamte Prozessgruppe. Eine Prozessgruppe wird<br />
durch zwei geschweifte Klammern begrenzt. Innerhalb der Prozessgruppe können<br />
die in Abschnitt 7.7.2 besprochenen Bedingungen zur Ausführung (etwa das Semikolon<br />
zur unbedingten Ausführung) verwendet werden.<br />
Prozessgruppe<br />
$ { ls; uname } | tee log.txt<br />
CVS<br />
Makefile<br />
TODO<br />
ZEITPLAN<br />
anhg_komref.tex<br />
...<br />
Linux<br />
Listing 7.59 Prozessgruppe<br />
Ohne Prozessgruppe müsste nun die Ausgabe jedes Prozesses explizit umgelenkt<br />
werden, aber mit Gruppe benötigen wir nur eine Ausgabeumlenkung, die wir in<br />
diesem Fall durch eine Pipe mit tee ersetzt haben.<br />
Startet man hingegen durch Verwendung normaler Klammern eine komplette Subshell<br />
(und damit einen neuen Prozess mit eigenen Bereichen im Stack) für eine<br />
Prozessgruppe, so erhält diese Subshell auch ihre eigenen Variablen.<br />
Subshell<br />
Wenn Sie also in der Subshell die Werte von Variablen verändern, so ändern sich die Werte<br />
nicht in der Parent-Shell.<br />
user$ katze=Felix<br />
user$ ( katze=Mauzi; echo $katze )<br />
Mauzi<br />
241
7 Die Shell<br />
user$ echo $katze<br />
Felix<br />
user$ { katze=Minka ; echo $katze }<br />
Minka<br />
user$ echo $katze<br />
Minka<br />
Listing 7.60 Das unterschiedliche Verhalten mit Shellvariablen<br />
Später werden wir uns noch mit der unterschiedlichen Nutzung von lokalen und<br />
globalen Variablen in Shellskriptfunktionen beschäftigen.<br />
Prozessgruppen im<br />
Hintergrund<br />
Prozessgruppen können problemlos im Hintergrund gestartet werden. Möchten Sie<br />
beispielsweise eine länger dauernde Dateisuche im Hintergrund ablaufen lassen,<br />
ist dies möglich, indem Sie die Anweisung, den Prozess im Hintergrund zu starten<br />
(&), hinter die schließende Prozessgruppenklammer stellen: { find / -name<br />
Dateiname ; find / -name DateinameB }&<br />
7.11 Effektives Arbeiten mit der Bash<br />
Dieses Unterkapitel soll Ihnen zeigen, wie man sich die tägliche Arbeit mit der bash<br />
(Bourne-Again-Shell) erleichtern kann.<br />
7.11.1 Die Kommando-History<br />
Das einfachste Feature der bash, das Ihnen etwas Arbeit abnimmt, sollten Sie unbedingt<br />
kennen: die Kommando-History. Sie speichert die zuletzt eingegebenen Befehle.<br />
Sie können diese abrufen und brauchen sie nicht erneut einzugeben, um<br />
sie wieder aufzurufen. Zudem bietet die bash die Möglichkeit, diese Befehle zu<br />
editieren.<br />
Eine Übersicht über die in der History enthaltenen Befehle liefert Ihnen ein bloßer<br />
Aufruf von history. Durch Angabe einer Nummer bekommen Sie die letzten n<br />
Einträge angezeigt.<br />
user$ history 3<br />
22 cvs commit -m ''<br />
23 exit<br />
24 history 3<br />
Listing 7.61 Das Kommando history<br />
Unerwünschte Einträge in der History können Sie über history -d <strong>aus</strong><br />
der History-Liste löschen.<br />
242
Effektives Arbeiten mit der Bash 7.11<br />
Nehmen wir einmal an, es wurde der Befehl find /usr/local/bin -name "Dateiname"<br />
<strong>aus</strong>geführt. Nun möchten Sie den gleichen Befehl mit einem anderen<br />
Dateinamen <strong>aus</strong>führen. Um nicht alles noch einmal eintippen zu müssen, können<br />
Sie durch die Cursor-Taste Nach oben den zuletzt eingegebenen Befehl in die<br />
Kommandozeile laden.<br />
Scrolleninder<br />
History<br />
Durch erneutes Betätigen der Nach-oben-Taste lädt die bash wiederum den Befehl,<br />
der vor dem letzten aufgerufen wurde, in die Kommandozeile und so weiter – so<br />
einfach ist das. Mit der Nach-unten-Taste können Sie die History wieder vorwärts<br />
durchsuchen.<br />
Um nun den alten find-Aufruf anzupassen, muss der neue Dateiname in die alte<br />
Kommandoeingabe eingefügt werden. Sie können sich mittels der Cursor-Tasten<br />
Nach links und Nach rechts in der Kommandozeile bewegen und an allen Positionen<br />
Zeichen löschen und einfügen.<br />
Das Ausrufezeichen hat eine ganz besondere Funktion in der bash. Esdientzum<br />
Aufruf von Befehlen <strong>aus</strong> der History.<br />
Den zuletzt eingegebenen Befehl können Sie durch zwei Ausrufezeichen wiederholt<br />
<strong>aus</strong>führen lassen:<br />
Editieren in der<br />
Befehlszeile<br />
Ausrufezeichen<br />
Vorheriger Befehl<br />
user$ uname -a<br />
OpenBSD eygo.sun 3.6 EYGO#0 i386<br />
user$ !!<br />
OpenBSD eygo.sun 3.6 EYGO#0 i386<br />
Listing 7.62 Erneutes Ausführen des letzten Befehls<br />
Ebenso können Sie durch Angabe der Befehlsnummer in der Kommando-History<br />
einen der darin gespeicherten Befehle wiederholen. Die History-Nummer eines<br />
Befehls erhalten Sie durch Aufruf des history-Befehls. Der Befehl wird dann durch<br />
!n (wobei n die Befehlsnummer ist) erneut <strong>aus</strong>geführt.<br />
user$ history 3<br />
392 make all view<br />
393 uname -a<br />
394 history 3<br />
user$ !393<br />
OpenBSD eygo.sun 3.6 EYGO#0 i386<br />
Listing 7.63 !n<br />
Ein äußerst praktisches Feature der bash ist das Suchen nach Befehlen durch Angabe<br />
der ersten Zeichen eines Befehls. Nun werden Sie sich wohl fragen, was man sich<br />
Suchen nach<br />
Befehlen<br />
243
7 Die Shell<br />
dennbitteschöndaruntervorstellenkann?Mankann–wiesooft–auchdiese<br />
Funktionalität am besten durch ein Beispiel erläutern.<br />
Ein Benutzer gibt zunächst den Befehl uname und anschließend den Befehl uptime<br />
ein. Nun möchte er erst uptime, später uname erneut aufrufen, ohne diese<br />
Befehle erneut einzugeben. Erst in der Kommando-History nachzusehen ist oftmals<br />
umständlich. Daher verwendet der Benutzer die Befehlssuche.<br />
Die simpelste Variante ist nun folgende: Der Benutzer gibt ein Ausrufezeichen und<br />
darauf unmittelbar folgend den ersten Buchstaben des Befehls, also ein »u«, ein.<br />
Daraufhin ruft die Shell den letzten Befehl auf, der mit »u« began, also uptime.<br />
Möchte der Benutzer nun aber uname aufrufen, so reicht es nicht, ein »u« hinter das<br />
Ausrufezeichen zu stellen. Hierzu muss noch der zweite Buchstabe des Befehls, also<br />
ein »n«, angegeben werden, worauf der letzte Befehl, der mit »un« begann, erneut<br />
<strong>aus</strong>geführt wird:<br />
user$ !u<br />
uptime<br />
9:20PM up 7:30, 3 users, load averages: 0.22,<br />
0.21, 0.17<br />
user$ !un<br />
uname<br />
OpenBSD<br />
Listing 7.64 Die Suche nach Befehlen<br />
Den letzten Befehl, der einen bestimmten String enthielt, können Sie durch den<br />
Aufruf von !? erneut <strong>aus</strong>führen lassen.<br />
Aus der Trickkiste<br />
Bedeutend komfortabler ist dies mit der Tastenkombination Strg + R zu bewerkstelligen.<br />
Bei diesem Verfahren wird Ihnen automatisch von der bash angezeigt,<br />
welcher Befehl <strong>aus</strong>geführt werden würde, während Sie die Kommandozeile editieren:<br />
(reverse-i-search)`un': uname<br />
Listing 7.65 Strg + R<br />
Teile alter Befehle<br />
ersetzen<br />
Erinnern Sie sich noch an den wiederholten Aufruf von find, den es zu editieren<br />
galt, um nach einem neuen Dateinamen zu suchen? Dies kann in der bash nochmals<br />
vereinfacht werden, sofern der Befehl find der zuletzt eingegebene war. Durch<br />
Angabe der zu ersetzenden Zeichenkette im letzten Befehl kann ein alter Befehl<br />
modifiziert <strong>aus</strong>geführt werden.<br />
244
Effektives Arbeiten mit der Bash 7.11<br />
Der besagte find-Aufruf sah folgendermaßen <strong>aus</strong>: find /usr/local/bin -name<br />
"Dateiname". Um nun nach dem Dateinamen zsh zu suchen und den gleichen<br />
Befehl zu verwenden, muss nach dem Muster<br />
ˆAlter-StringˆNeuerStringˆ<br />
eine Manipulation des alten Befehls erfolgen, also:<br />
user$ find /usr/local/bin -name "Dateiname"<br />
...<br />
user$ ˆDateinameˆzshˆ<br />
find /usr/local/bin -name "zsh"<br />
/usr/local/bin/zsh<br />
Listing 7.66 Das Kommando find mit neuem Dateinamen<br />
7.11.2 Automatische Vervollständigung von Dateinamen<br />
Ein ähnlich praktisches Feature wie die Kommando-History stellt die automatische<br />
Vervollständigung von Dateinamen dar. Sie wird in der bash durch die Tab-Taste<br />
angesteuert. Da unter Unix auch Programme Dateien darstellen, funktioniert dieses<br />
Feature natürlich auch mit diesen.<br />
Bei der Nutzung der Tab-Taste sind allerdings zwei Fälle zu unterscheiden:<br />
<br />
<br />
Es ist nur eine passende Datei vorhanden.<br />
Es sind mehrere passende Dateien vorhanden.<br />
Für den ersten Fall erstellen wir ein Beispielverzeichnis, in dem wir eine Datei mit<br />
dem Namen abc.txt unterbringen.<br />
Nur ein Kandidat<br />
$ mkdir test<br />
$ touch test/abc.txt<br />
$ cd test<br />
Listing 7.67 Beispielverzeichnis mit einer Datei erstellen<br />
VerwendenwirnuneinProgrammwie/bin/ls, dem wir diese Datei als Parameter<br />
übergeben, müssen wir, da es nur eine Datei im Verzeichnis gibt, bloß die Tab-Taste<br />
betätigen, und die bash setzt uns den Dateinamen automatisch an die gewünschte<br />
Position in der Eingabe.<br />
Versuchen Sie es einmal selbst: Wechseln Sie in das neue Verzeichnis, geben Sie ls<br />
und ein Leerzeichen ein, und drücken Sie die Tab-Taste. Die bash sollte nun den<br />
Dateinamen abc.txt automatisch in die Befehlszeile schreiben.<br />
245
7 Die Shell<br />
Mehrere<br />
Kandidaten<br />
Gleiche<br />
Anfangsbuchstaben<br />
Nun erstellen wir im Verzeichnis noch eine Datei mit dem Namen xyz.txt.WennSie<br />
das letzte Beispiel unter den neuen Bedingungen wiederholen, wird es nicht ohne<br />
weiteres funktionieren. Die bash weiß nicht von selbst, welche der beiden Dateien<br />
sie als Parameter übergeben soll. Der Trick funktioniert nun so, dass so viele Zeichen<br />
des Dateinamens eingegeben werden, bis es nur noch einen Dateinamen gibt, auf<br />
den die ersten Zeichen zutreffen – in diesem Fall genügt der erste Buchstabe der<br />
Datei (entweder ein »a« oder ein »x«), da kein Dateiname gleiche Zeichen enthält.<br />
Wird dann erneut die Tab-Taste gedrückt, vervollständigt die bash den Dateinamen<br />
wieder automatisch.<br />
Doch die bash kann Ihnen noch ein Stück Arbeit abnehmen. Nehmen wir an, es<br />
seien zwei Dateien abc und abd in einem Verzeichnis vorhanden. Sofern es sowieso<br />
keine Wahl zwischen den Zeichen gibt, bringt eine Betätigung der Tab-Taste immer<br />
diese Zeichen auf den Monitor. Drücken Sie also in solch einem Verzeichnis die<br />
Tab-Taste, so schreibt die bash Ihnen die beiden ersten Zeichen (da diese sowieso<br />
gleich sind und von Ihnen eingegeben werden müssten) auf den Bildschirm. Sie<br />
müssen anschließend nur noch ein »c« bzw. »d« eingeben.<br />
Für den Fall, dass im Verzeichnis noch die Datei xyz vorhanden ist, müsste der erste<br />
Buchstabe wieder eingegeben werden, da nun wieder zwei Fälle eintreten könnten.<br />
Doppel-Tab<br />
Wenn mehrere Dateien vorhanden sind, können Sie die Tab-Taste auch zweimal<br />
betätigen, um sich während der Befehlseingabe eine Übersicht über die Dateien im<br />
Verzeichnis zu verschaffen. Durch dieses doppelte Betätigen liefert Ihnen die bash<br />
immer die nach Ihrer bisherigen Eingabe noch möglichen Datei<strong>aus</strong>wahlen.<br />
Das bedeutet im Beispiel: Hätten Sie wieder die drei Dateien xyz, abc und abd<br />
im Verzeichnis, so würde Ihnen die bash zunächst alle drei auflisten. Wenn Sie<br />
dann ein »a« eingeben und die Tab-Taste drücken, gibt Ihnen die bash das »b«<br />
(die einzig sinnvolle Möglichkeit) auf dem Bildschirm <strong>aus</strong>. Wenn Sie dann wieder<br />
doppelt die Tab-Taste betätigen, gibt Ihnen die bash nun die beiden noch möglichen<br />
Dateinamen abc und abd <strong>aus</strong>.<br />
Weiterhin ist das Tab-Taste »intelligent«: Am Anfang einer Shelleingabe ist nur ein<br />
<strong>aus</strong>führbares Kommando sinnvoll – entsprechend werden auch nur <strong>aus</strong>führbare<br />
Dateien bzw. Shellbuiltins vervollständigt.<br />
7.12 xargs<br />
Zum Abschluss des einleitenden Shellkapitels möchten wir noch ein Tool namens<br />
xargs vorstellen. Es leitet die Ausgabe des ersten Programms nicht als Eingabe (wie<br />
in einer Pipe), sondern als Parameter für ein zweites Programm weiter.<br />
246
Zusammenfassung 7.13<br />
Soll beispielsweise die Ausgabe von ls als Parameter für grep (ein Tool, das den<br />
Dateiinhalt nach einem vorgegebenen Muster durchsucht) herhalten, würde man<br />
dies folgendermaßen realisieren:<br />
$ ls *.tex | xargs grep gpKapitel<br />
anhg_komref.tex:\gpKapitel{Kommandoreferenz}<br />
...<br />
kap01_kernel.tex:\gpKapitel{Der Kernel}<br />
kap05_sysadmin.tex:\gpKapitel{Systemadministration}<br />
kapxx_software.tex:\gpKapitel{Softwareentwicklung}<br />
Listing 7.68 ls und xargs mit grep<br />
7.13 Zusammenfassung<br />
In diesem Kapitel wurden die <strong>Grundlagen</strong> der Unix-Shells besprochen. Dabei gibt<br />
es zwei primäre Shellzweige: den der Bourne-Shell, zu dem die Bourne-Shell selbst,<br />
die ksh und die bash sowie einige weniger bekannte Shells gehören, und den Zweig<br />
der C-Shell, zu dem die C-Shell (csh) unddietcsh gehören. Des Weiteren gibt es<br />
noch exotische Shells wie die Scheme-Shell.<br />
Außerdem wurde mit den Aliasen eine Möglichkeit besprochen, (komplexe) Kommandos<br />
über einen kurzen Ersatzbefehl aufzurufen, sowie die Kommandosubstitution,<br />
die es ermöglicht, eine Ausgabe eines Befehls als Eingabe oder Wert für andere<br />
Befehle und Variablen zu nutzen.<br />
Als kleinen Ausblick auf die Shellskriptprogrammierung wurden Shellvariablen sehr<br />
intensiv behandelt.<br />
Sie haben erste Formen der Interprozess-Kommunikation (IPC) kennengelernt: Pipes<br />
und FIFOs. Diese leiten die Ausgaben eines Programms an ein anderes weiter,<br />
wobei FIFOs als Dateien im Dateisystem vorliegen und mit dem Befehl mkfifo<br />
erzeugt werden.<br />
Angelehnt an die IPC wurde die Ein- und Ausgabeumlenkung vorgestellt – ein ebenfalls<br />
elementares Shell-Feature, das es ermöglicht, die Ausgabe eines Programms in<br />
eine Datei umzuleiten oder einen Dateiinhalt als Programm-Input zu nutzen.<br />
Einem weiteren Erkundungsgang durch die Shell mit dem nächsten Kapitel steht<br />
nun also nichts mehr im Wege – besonders nicht, nachdem Sie sich die tägliche Arbeit<br />
mit der Shell nun durch die Kommando-History sehr einfach machen können.<br />
247
7 Die Shell<br />
7.14 Aufgaben<br />
Alias-Wirrwarr<br />
Was geben die folgenden Befehle <strong>aus</strong>?<br />
$ alias q=ls<br />
$ alias q=`q;ls'<br />
$ q<br />
...<br />
Listing 7.69<br />
Für angehende Experten<br />
Was passiert, nachdem die folgenden Befehle in der bash <strong>aus</strong>geführt wurden?<br />
$ uname | tee /tmp/mylog<br />
Linux<br />
$ !?na > x<br />
$ alias displayX=`cat x`<br />
$ displayX<br />
...<br />
Listing 7.70<br />
Wie geht das?<br />
Wie können Programme wie chsh (zum Ändern der Login-Shell) oder passwd (zum<br />
Ändern des Passworts) die Passwortdateien modifizieren, obwohl sie von nicht<br />
priviligierten Benutzern <strong>aus</strong>geführt werden können?<br />
248
»Wenn das Aug’ nicht sehen will,<br />
So helfen weder Licht noch Brill’.«<br />
–Sprichwort<br />
19 LAMP & Co.<br />
In diesem Kapitel wollen wir uns mit einer sehr populären Erscheinung <strong>aus</strong>einandersetzen.<br />
Die ganze Welt spricht von LAMP – Linux mit Apache, MySQL und<br />
PHP 1 . Mit dieser Open-Source-Kombination kann man einen voll funktionsfähigen<br />
Web-Applikationsserver aufsetzen. Die Webseiten können dabei aufgrund der jeweiligen<br />
Skriptsprache – in der Regel PHP – dynamisch gestaltet und mit einem<br />
Datenbankzugriff auf das MySQL-Backend <strong>aus</strong>gestattet werden.<br />
Dieses Konzept ist nun in aller Munde, weil bei einem solchen Einsatz ein völlig<br />
lizenzkostenfreies System entsteht. Gleichzeitig hat man mit Apache, PHP und<br />
MySQL auf Marktführer beziehungsweise Quasistandards gesetzt. In diesem Kapitel<br />
zeigen wir Ihnen, wie Sie einen solchen LAMP-Webserver aufsetzen und im Prinzip<br />
mit ihm arbeiten.<br />
Lizenzfreies Setup<br />
Die Installation<br />
Die Grundlage für ein solches Setup ist ein frisches, pures Linux-System ohne allzu<br />
viel Schnickschnack. Wie Sie verschiedene Linux-Distributionen installieren, erfahren<br />
Sie in Kapitel 2. Vermeiden sollten Sie dabei vor allem die grafische Oberfläche<br />
X11 sowie andere Netzwerkdienste wie SMTP- oder POP3-Server.<br />
Bei Serversystemen sollte man sich nämlich auf das Wesentliche beschränken. Wenn<br />
man einen SMTP-Dienst auf einem Webserver nur laufen lässt, weil dieser zufällig<br />
bei jeder Installation der Lieblingsdistribution mit auf die Platte geschaufelt wird,<br />
so tut man höchstens einem Angreifer einen Gefallen – denn alle anderen brauchen<br />
den Dienst nicht, er hingegen hat eine weitere Angriffsmöglichkeit.<br />
19.1 Apache<br />
Nicht nur beim Basteln der eigenen Homepage kann ein Webserver hilfreich sein.<br />
In Zeiten von immer billiger werdenden Flatrates und virtuellen Servern (V-Servern)<br />
1 Manchmal wird das »P« <strong>aus</strong> LAMP auch als Abkürzung für Perl oder Python interpretiert.<br />
631
19 LAMP & Co.<br />
wird auch ein eigener Internetserver immer verbreiteter. Ein HTTP-Dienst gehört<br />
bei einem solchen Setup eigentlich auch immer dazu.<br />
Als Software empfehlen wir dabei das »A« <strong>aus</strong> LAMP: Apache – den im Internet<br />
am weitesten verbreiteten Webserver. Aufgrund seiner Verbreitung ist es ziemlich<br />
wahrscheinlich, dass Ihre Distribution bereits ein Apache-Paket enthält.<br />
Etwas zur Geschichte<br />
Der Grund für den Erfolg von Apache liegt sicherlich in seiner Geschichte. Unter der<br />
Bezeichnung »NCSA HTTPd« wurde er als einer der ersten Webserver vom National<br />
Center for Supercomputing Applications an der University of Illinois entwickelt.<br />
ApatchyServer<br />
Irgendwann wurde der Support für das Produkt allerdings eingestellt, und die<br />
Administratoren der zahlreichen NCSA-Installationen, die es bis dahin gab, waren<br />
auf sich allein gestellt. Schon bald kursierten viele Patches und Erweiterungen.<br />
Diese Bestrebungen wurden später im Apache-Projekt koordiniert, dessen Name<br />
sich <strong>aus</strong> dieser Geschichte erklärt: APAtCHysErver.<br />
Viele Jahre lang wurde der Apache-Server in der Version 1.3.x eingesetzt, die auch<br />
wir noch in der ersten Auflage dieses Buches besprochen haben. Für Neuinstallationen<br />
wird allerdings praktisch kaum mehr auf Version 1.3.x zurückgegriffen,<br />
weshalb wir uns im Folgenden auf die Apache-Version 2.x konzentrieren werden.<br />
Die Datei »apache2.conf«<br />
Konfiguration<br />
Im Folgenden wollen wir den Apache konfigurieren. 2 Dazu editieren wir die Datei<br />
apache2.conf, die sich meistens in /etc/apache2 bzw. /etc/httpd befindet. Die<br />
Datei ist relativ groß – kein Wunder bei einer so wichtigen und umfangreichen<br />
Software. Falls die Datei bei Ihnen eher klein ist, dann wird es wahrscheinlich mehrere<br />
Include-Anweisungen geben, die andere Konfigurationsdateien in diese Datei<br />
einbinden (etwa ports.conf zur Konfiguration der Ports, auf denen der Apache Verbindungen<br />
entgegennimmt). Eine Übersicht über die Include-Anweisungen Ihrer<br />
apache2.conf-Datei liefert Ihnen ein grep-Aufruf:<br />
$ grep Include /etc/apache2/apache2.conf<br />
# Include module configuration:<br />
Include /etc/apache2/mods-enabled/*.load<br />
Include /etc/apache2/mods-enabled/*.conf<br />
# Include all the user configurations:<br />
Include /etc/apache2/httpd.conf<br />
# Include ports listing<br />
2 Die Installation haben Sie bestimmt schon ganz selbstständig über das Paketverwaltungstool<br />
Ihrer Distribution erledigt – vielleicht haben Sie sich sogar die Quellen von apache.org gezogen<br />
und selbst übersetzt. :-)<br />
632
Apache 19.1<br />
Include /etc/apache2/ports.conf<br />
# Include of directories ignores editors' and<br />
# dpkg's backup files,<br />
# Include generic snippets of statements<br />
Include /etc/apache2/conf.d/<br />
# Include the virtual host configurations:<br />
Include /etc/apache2/sites-enabled/<br />
Listing 19.1 Welche Include-Befehle enthält die apache2.conf-Datei?<br />
Wie Sie sehen, existieren für den Apache eine ganze Reihe an Include-Anweisungen,<br />
die teilweise sogar ganze Unterverzeichnisse wie mods-enabled einbinden. Aber keine<br />
Sorge: Hauptsächlich werden wir in diesem Buch Konfigurationsparameter <strong>aus</strong><br />
den Dateien apache2.conf, httpd.conf und ports.conf besprechen, schließlich handelt<br />
es sich nur um eine Einführung. In welcher Datei sich ein Konfigurationsparameter<br />
befindet, erfahren Sie jeweils durch grep -R [Parameter-Name] /etc/apache2.<br />
Um beispielsweise her<strong>aus</strong>zufinden, in welcher Konfigurationsdatei der Parameter<br />
PidFile versteckt ist, ist folgendes Kommando nötig:<br />
$ grep -R PidFile /etc/apache2/<br />
/etc/apache2/apache2.conf:# PidFile: The file in which the<br />
server should record its process<br />
/etc/apache2/apache2.conf:PidFile $APACHE_PID_FILE<br />
Listing 19.2 Her<strong>aus</strong>finden, in welcher Datei ein Parameter verwendet wird<br />
Doch lassen Sie uns nun die wichtigsten Konfigurationsparameter des Apache-2.x<br />
beschreiben.<br />
# Standalone-Server auf Port 80<br />
Listen 80<br />
PidFile<br />
/var/run/apache2.pid<br />
Listing 19.3 Grundkonfiguration<br />
Unser Apache läuft auf Port 80 (Listen 80). Sie können durch mehrere Listen-<br />
Befehle auch erzwingen, dass der Apache-Server parallel auf mehreren unterschiedlichen<br />
Ports läuft. Um den Server an eine bestimmte IP-Adresse zu binden (hierbei<br />
funktionieren auch IPv6-Adressen), genügt ein Listen-Befehl der Form Listen<br />
Adresse:Port, alsoetwaListen 192.168.2.99:8080. IndieunterPidFile angegebene<br />
Datei schreibt der Dienst nach dem Start seine Prozess-ID hinein.<br />
Listen, PidFile<br />
Timeout 300<br />
Listing 19.4 Timeout<br />
633
19 LAMP & Co.<br />
Timeout<br />
Mit dem Timeout-Befehl geben Sie die Anzahl Sekunden an, nach denen eine Verbindung<br />
durch ein Netzwerk-Timeout beim Senden oder Empfangen geschlossen<br />
wird.<br />
User<br />
Group<br />
www-data<br />
www-data<br />
Listing 19.5 Rechte<br />
Kein root<br />
Mit den folgenden beiden Anweisungen legen Sie die Rechte fest, unter denen<br />
der Prozess laufen soll. Auf keinen Fall sollten hier administrative root-Rechte<br />
vergeben werden. Wichtig ist nur, dass der betreffende Benutzer Zugriff auf das<br />
DocumentRoot-Verzeichnis mit allen Webseiten hat.<br />
DefaultType text/plain<br />
HostnameLookups Off<br />
Listing 19.6 Weitere Konfigurationsparameter<br />
DefaultType<br />
HostnameLookups<br />
Mit der Option DefaultType gebenSiedenimNormalfallzuverwendendenMIME-<br />
Typ für Dokumente an, bei denen der Server diesen nicht selbst feststellen kann.<br />
Diesen Wert müssen Sie im Normalfall nicht verändern.<br />
Für die Option HostnameLookups können Sie die Werte On, Double oder Off vergeben.<br />
Wenn Sie die Option mit On aktivieren, versucht der Apache-Server die<br />
IP-Adressen von Clients über einen Nameserver in Hostnamen umzusetzen. In Ihren<br />
Logdateien finden Sie dann entsprechend den Hostname eines Clients anstelle<br />
seiner IP-Adresse. Sollten Sie nach einem DNS-Reverse-Lookup noch ein Forward-<br />
Lookup durchführen wollen, können Sie die Option Double verwenden. Laut Apache-Dokumentation<br />
ist die Option standardmäßig auf Off gestellt, um Netzwerktraffic<br />
zu sparen und schneller die Anfragen von Clients beantworten zu können.<br />
ErrorLog<br />
LogLevel<br />
CustomLog<br />
/var/log/apache2/error.log<br />
warn<br />
/var/log/apache2/others.log vhost_combined<br />
Listing 19.7 Logdateien<br />
ErrorLog, LogLevel<br />
und CustomLog<br />
Wichtige Konfigurationsparameter sind auch solche, die die Protokollierung (das<br />
Logging) betreffen. Dabei ist zu beachten, dass die in der apache2.conf enthaltenen<br />
Einstellungen nur für virtuelle Hosts gelten, wenn die Parameter bei deren<br />
Konfiguration nicht gesetzt wurden – aber dazu später mehr.<br />
Über die durch ErrorLog angegebene Logdatei werden Fehlermeldungen protokolliert.<br />
Der LogLevel kann den Wert debug, info, notice, warn, error, crit, alert<br />
oder emerg annehmen. Der Unterschied der einzelnen Werte liegt darin, wie detail-<br />
634
Apache 19.1<br />
liert die Protokollierung erfolgen soll. Während debug alles protokolliert (selbst das<br />
Öffnen einer Datei!) und Ihnen die Festplatte mit solchen Meldungen praktisch zumüllt,<br />
wodurch durch<strong>aus</strong> wichtige Meldungen untergehen können, gibt Ihnen das<br />
andere Extrem emerg nur Notfall-Warnungen <strong>aus</strong>. Es ist sinnvoll, die Voreinstellung<br />
(warn) beizubehalten. Sollten Sie etwas <strong>aus</strong>führlichere Informationen benötigen,<br />
können Sie auch einmal notice oder (die Vorstufe zu debug) info <strong>aus</strong>probieren.<br />
CustomLog legt die eigentliche Logdatei, die Zugriffe enthält, fest. Beachten Sie, dass<br />
in dieser Datei HTTP-Requests protokolliert werden; Fehlermeldungen werden in<br />
die über ErrorLog angegebene Datei geschrieben.<br />
ServerRoot<br />
"/etc/apache2"<br />
Listing 19.8 ServerRoot<br />
In diesem Verzeichnis sucht der Apache weiter nach verschiedenen Konfigurationsdateien.<br />
Dieses Verzeichnis kann je nach Distribution auch anders heißen und<br />
braucht in der Regel nicht geändert zu werden.<br />
$ ls -l /etc/apache2/mods-enabled/mime.load \<br />
/etc/apache2/mods-enabled/dir.load<br />
lrwxrwxrwx 1 root root 26 Feb 15 2007<br />
/etc/apache2/mods-enabled/dir.load -><br />
../mods-available/dir.load<br />
lrwxrwxrwx 1 root root 27 Feb 15 2007<br />
/etc/apache2/mods-enabled/mime.load -><br />
../mods-available/mime.load<br />
Listing 19.9 Module aktivieren<br />
Apache kennt zudem Module, die seine Funktionalität erweitern (es gibt beispielsweise<br />
ein PHP-Modul). Die verfügbaren installierten Module finden sich dabei<br />
meist im Unterverzeichnis mods-available/ des ServerRoot-Verzeichnisses. Um ein<br />
Modul zu aktivieren, wird ein symbolischer Link im Verzeichnis mods-enabled auf<br />
die entsprechende Datei im Verzeichnis mods-available/ erstellt. Eine Übersicht der<br />
aktivierten Module erhalten Sie daher ganz einfach über einen Blick in das Verzeichnis:<br />
Module<br />
$ ls mods-enabled/<br />
alias.conf cgi.load php5.conf<br />
alias.load dir.conf php5.load<br />
auth_basic.load dir.load rewrite.load<br />
authn_file.load env.load ruby.load<br />
authz_default.load fastcgi.conf setenvif.conf<br />
authz_groupfile.load fastcgi.load setenvif.load<br />
authz_host.load mime.conf status.conf<br />
635
19 LAMP & Co.<br />
authz_user.load mime.load status.load<br />
autoindex.conf negotiation.conf<br />
autoindex.load negotiation.load<br />
Listing 19.10 Aktivierte Apache-Module<br />
In diesem Fall wurde eine ganze Reihe an Modulen geladen, die unterschiedlich<br />
wichtig sind. Eines der wichtigsten Module ist mime; es bringt unserem Webserver<br />
bei, unterschiedliche Datentypen zu verstehen und vor allem, dies dem Browser<br />
mitzuteilen. Nur so kann dieser wissen, ob er gerade eine Webseite (also HTML-<br />
Code) oder ein JPEG-Bild (also Binärdaten) lädt.<br />
Ein weiteres wichtiges Modul ist dir; es lässt den Webserver nach einem »Standard-<br />
dokument« suchen, wenn in der URL nichts weiter angegeben wurde. So gelangt<br />
man beim Aufruf von example.com auf die Seite example.com/index.html –oder,<br />
wenn sie im entsprechenden Verzeichnis vorhanden ist, auf die Seite /index.htm.<br />
index.html finden<br />
Virtuelle Hosts und DocumentRoot<br />
DocumentRoot<br />
Im Apache kann für jede Site, die auf dem Server läuft, ein eigenes Verzeichnis für<br />
die angebotenen Webdateien festgelegt werden. Die Standardsite (default site) wird<br />
über die Datei sites-available/default konfiguriert. In diesem Abschnitt legt man nun<br />
fest, dass das Wurzelverzeichnis für Webdokumente /var/www ist. Lädt man also<br />
http://www.example.com/index.html, so wird die lokale Datei /var/www/index.html<br />
an den Client gesendet.<br />
DocumentRoot /var/www/<br />
<br />
Options FollowSymLinks<br />
AllowOverride None<br />
<br />
<br />
Options Indexes FollowSymLinks MultiViews<br />
AllowOverride None<br />
Order allow,deny<br />
allow from all<br />
# This directive allows us to have apache2's default start page<br />
# in /apache2-default/, but still have / go to the right place<br />
RedirectMatch ^/$ /apache2-default/<br />
<br />
Listing 19.11 Die Datei /etc/apache2/sites-available/default (Ausschnitt)<br />
Virtual Hosts<br />
Im Zusammenhang mit Sites spricht man auch von virtuellen Hosts (engl. virtual<br />
hosts). Liefert Ihr Webserver etwa bisher die Site meine-site.xyz und soll nun noch<br />
636
Apache 19.1<br />
eine weitere Site tolle-site.abc zur Verfügung stellen, können Sie für die neue Site<br />
einen neuen virtuellen Host anlegen.<br />
Dazu muss zunächst im Verzeichnis sites-available eineDateifürdieneueSiteangelegt<br />
werden (kopieren Sie dazu einfach die default-Site): cp default tolle-site.abc.<br />
Die neue Datei bearbeiten Sie so, dass Sie ihr ein neues Verzeichnis verpassen (über<br />
DocumentRoot) und über ServerName die neue Domain konfigurieren, damit Apache<br />
weiß, für welche Domain er das neue DocumentRoot verwenden soll. Weitere Alternativ-Domains<br />
(etwa mit www-Subdomain) können durch ServerAlias angegeben<br />
werden. Insgesamt sieht Ihre neue Datei dann in etwa so <strong>aus</strong>:<br />
<br />
ServerAdmin ich@mein-mail-provider.xyz<br />
ServerName tolle-site.abc<br />
ServerAlias www.tolle-site.abc<br />
DocumentRoot /var/www/tolle-site<br />
<br />
Options FollowSymLinks<br />
AllowOverride None<br />
<br />
ErrorLog /var/log/apache2/meine-tolle-site.error.log<br />
# Possible values include: debug, info, notice, warn, error,<br />
# crit, alert, emerg.<br />
LogLevel info<br />
CustomLog /var/log/apache2/meine-tolle-site.access.log combined<br />
<br />
Listing 19.12 Virtual Host mit Apache<br />
Sämtliche Anweisungen, die sich im VirtualHost-Block befinden (der mit <br />
abgeschlossen wird) beziehen sich dabei auf Ihren neuen virtuellen Host.<br />
Wichtig ist hierbei noch, dass über die ErrorLog-Anweisung und die Anweisung<br />
CustomLog zwei zusätzliche Logdateien konfiguriert wurden. Unterschiedliche Logdateien<br />
für unterschiedliche virtuelle Hosts zu erstellen, können wir Ihnen nur<br />
empfehlen, da dadurch die Übersichtlichkeit der Logmeldungen erhalten bleibt.<br />
Um den virtuellen Host zu aktivieren, müssen Sie nun einen symbolischen Link im<br />
Verzeichnis sites-enabled erstellen:<br />
637
19 LAMP & Co.<br />
# cd /etc/apache2<br />
# ln -s sites-available/meine-tolle-site \<br />
sites-enabled/100-meine-tolle-site<br />
Listing 19.13 Den neuen virtuellen Host aktivieren<br />
Anschließend muss der Server neu gestartet werden, was wir im Folgenden beschreiben.<br />
19.1.1 Apache verwalten<br />
Natürlich muss man einen Serverdienst wie den Apache auch zur Laufzeit verwalten<br />
können. Im Folgenden wollen wir kurz auf das Tool apache2ctl und die wichtigsten<br />
Logfiles eingehen.<br />
apache2ctl<br />
Mit dem Programm apache2ctl kann man Apache kontrollieren. Dazu gehört neben<br />
den Möglichkeiten des Startens, Neustartens und Stoppens natürlich auch die<br />
Option, die Konfigurationsdatei auf Korrektheit hin zu überprüfen. Hier eine Übersicht<br />
über die Möglichkeiten des Tools:<br />
# Die Konfiguration testen:<br />
# apache2ctl configtest<br />
# Den Server starten:<br />
# apache2ctl start<br />
# Den Server beenden:<br />
# apache2ctl stop<br />
# Den Server neustarten:<br />
# apache2ctl restart<br />
# Statusbericht anzeigen<br />
# apache2ctl status / fullstatus<br />
Listing 19.14 apache2ctl<br />
Konfigurationsdatei<br />
prüfen<br />
Ist die apache2.conf fehlerhaft, so wird bei apache2ctl configtest ein Fehler <strong>aus</strong>gegeben.<br />
Mit dieser Hilfe kann das Problem dann oft recht einfach und schnell<br />
behoben werden. Nach einer eventuellen Änderung an der apache2.conf kann Apache<br />
dann mit der restart-Option neu gestartet werden:<br />
638
Apache 19.1<br />
# apachectl restart<br />
/usr/sbin/apachectl restart: httpd restarted<br />
Listing 19.15 Apache neu starten<br />
Ebenfalls interessant ist die Möglichkeit, sich über den Status des Servers informieren<br />
zu lassen. Dafür kann man entweder den Parameter status oder – für noch<br />
mehr Informationen – den Parameter fullstatus verwenden:<br />
$ apache2ctl fullstatus<br />
Apache Server Status for localhost<br />
Server Version: Apache/2.2.12 (Ubuntu) mod_fastcgi/2.4.6<br />
PHP/5.2.10-2ubuntu6.4 with Suhosin-Patch<br />
mod_ruby/1.2.6 Ruby/1.8.7(2009-06-12)<br />
Server Built: Mar 9 2010 22:11:44<br />
_________________________________________<br />
Current Time: Friday, 02-Apr-2010 15:52:48 CEST<br />
Restart Time: Friday, 02-Apr-2010 10:43:33 CEST<br />
Parent Server Generation: 0<br />
Server uptime: 5 hours 9 minutes 14 seconds<br />
1 requests currently being processed, 4 idle workers<br />
W____...........................................................<br />
................................................................<br />
................................................................<br />
................................................................<br />
Scoreboard Key:<br />
"_" Waiting for Connection, "S" Starting up, "R" Reading<br />
Request,<br />
"W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,<br />
"C" Closing connection, "L" Logging, "G" Gracefully<br />
finishing,<br />
"I" Idle cleanup of worker, "." Open slot with no current<br />
process<br />
Listing 19.16 apache2ctl zeigt den Status des Apache an<br />
Eine vollständige Liste der von Ihrem apache2ctl-Programm unterstützten Funktionen<br />
und Befehle finden Sie in der zugehörigen Manpage.<br />
639
19 LAMP & Co.<br />
Module<br />
Diese wenigen Direktiven reichen nun bereits <strong>aus</strong>, um einen einfachen kleinen<br />
Webserver mit Apache zu betreiben. Natürlich gibt es noch viel mehr als die bisher<br />
hier vorgestellten Module. Teilweise bringen diese auch ihre eigenen Schlüsselwörter<br />
mit, über die entsprechende Funktionalität konfiguriert werden kann. Häufig<br />
genutzte Module sind unter anderem:<br />
Sicheres Surfen<br />
<br />
<br />
<br />
mod_cgi.so<br />
Mit diesem Modul kann man CGI-Skripte nutzen. Das CGI (Common Gateway<br />
Interface) war historisch die erste Möglichkeit, interaktive Webinhalte zu gestalten.<br />
libphp5.so<br />
Mit diesem Modul kann man in PHP erstellte Webseiten mit dem Apache darstellen.<br />
PHP selbst ist, wie viele andere Erweiterungen, nicht Teil der Standard-<br />
Apache-Distribution 3 und muss separat installiert werden. Eine gute Adresse für<br />
alles rund um PHP ist www.php.net.<br />
mod_ssl.so<br />
Mit diesem Modul kann man einen HTTPS-Server aufsetzen und damit über<br />
den sogenannten Secure Sockets Layer eine verschlüsselte Verbindung zwischen<br />
Client und Server aufbauen.<br />
Je nach Distribution gibt es nun spezielle Pakete, die den Apache mit der einen<br />
oder anderen Funktion nachrüsten, sowie Pakete, die einen zum Beispiel bereits für<br />
SSL vorkonfigurierten Apache installieren.<br />
Die Logdateien<br />
Standardmäßig schreibt der Apache in zwei unterschiedliche Logdateien. Die Datei<br />
access.log wird zur Protokollierung einzelner Zugriffe genutzt; in error.log werden<br />
nur Fehler geschrieben.<br />
Kontrolle<br />
Beide Dateien befinden sich oft in einem Verzeichnis unterhalb von /var/log/ beziehungsweise<br />
von /usr/local/(apache2/), falls Sie den Apache von Hand <strong>aus</strong> den<br />
Quellen kompiliert haben.<br />
85.181.56.167 - - [05/Sep/2007:22:35:38 +0200] "GET<br />
/favicon.ico HTTP/1.1" 200 1406 "-" "Mozilla/5.0<br />
(Windows; U; Windows NT 5.1; de; rv:1.8.1.5)<br />
Gecko/20070713 Firefox/2.0.0.5"<br />
Listing 19.17 Eine Zeile <strong>aus</strong> der access.log-Datei<br />
3 Bei diesem umfangreichen Projekt spricht man auch von einer »Distribution«, beachten Sie<br />
jedoch den Unterschied zu den Linux-Distributionen.<br />
640
MySQL 19.2<br />
Hier sehen Sie eine Zeile <strong>aus</strong> access.log. Wie Sie bemerken, schickt Ihr Browser<br />
sehr viele Informationen über sich und das entsprechende Betriebssystem mit.<br />
Außerdem können Sie noch ablesen, dass die Anfrage nach index.html vom Rechner<br />
172.20.2.1 kam.<br />
[Sun Jul 01 08:52:23 2007] [error] [client 66.249.66.180]<br />
File does not exist: /var/www/robots.txt<br />
[Sun Jul 01 09:15:00 2007] [error] [client 65.55.208.135]<br />
File does not exist: /var/www/robots.txt<br />
Listing 19.18 Ausschnitt <strong>aus</strong> der Datei error.log<br />
An dieser Stelle können Sie feststellen, wofür error.log außer für die Fehler-Eintragungen<br />
sonst noch genutzt wird: für Servernachrichten. Im Beispiel sehen Sie die<br />
Nachrichten, die der Apache bei unserem Restart hinterlassen hat.<br />
19.2 MySQL<br />
Das »M« in LAMP steht für die freie Datenbank MySQL. Egal ob Webshop, Blog<br />
oder Auktionsbörse: Ohne Datenbank geht in der Regel nichts. Eine sehr gute Open-<br />
Source-Lösung ist MySQL. Diese Datenbank ist recht einfach zu administrieren und<br />
reicht vom Funktionsumfang her auch für größere Projekte noch <strong>aus</strong>.<br />
19.2.1 Administration<br />
Nach der Installation der entsprechenden Pakete <strong>aus</strong> der Distribution Ihrer Wahl<br />
stehen Sie schließlich vor der Frage, was Sie nun mit diesem Datending machen<br />
sollen. In der Regel ist die Datenbank nach ihrer Installation sofort einsatzbereit –<br />
es sei denn, die Distribution konfiguriert sie so, dass sie zum Beispiel nur für den<br />
lokalen Gebrauch nutzbar ist.<br />
Eine solche Vorgehensweise wird zum Beispiel oft bei Debian oder Slackware angewandt,<br />
um dem unerfahrenen Benutzer keine potenziellen Gefahren frei H<strong>aus</strong> zu<br />
liefern. Wenn Ihre Datenbank also standardmäßig nur auf dem Loopback-Interface<br />
und damit nur lokal zu erreichen ist, wissen Sie zumindest, was Sache ist. Meist<br />
sind aber die entsprechenden Optionen in den zugehörigen Konfigurationsdateien<br />
<strong>aus</strong>führlich kommentiert, so dass im Fall von MySQL ein kurzer Blick in die Datei<br />
my.cnf das Problem lösen sollte.<br />
mysql<br />
In jedem Fall sollte das Tool mysql zur Administration lokal funktionieren. Alternativ<br />
kann man mittels der Option -h auch auf eine entfernte Datenbank zugreifen.<br />
Auf der Konsole!<br />
641
19 LAMP & Co.<br />
In jedem Fall müssen Sie jedoch einen bestimmten Usernamen und ein Passwort<br />
für den Zugriff auf die Datenbank angeben:<br />
$ mysql -h host -u user -p<br />
Enter password: ********<br />
Welcome to the MySQL monitor. Commands end with ; or \g.<br />
Your MySQL connection id is 1090639<br />
Server version: 5.0.51a-24+lenny5 (Debian)<br />
Type 'help;' or '\h' for help. Type '\c'<br />
to clear the buffer.<br />
mysql><br />
Listing 19.19 Einloggen<br />
Anschließend öffnet sich ein Prompt, und Sie können mit der Datenbank kommunizieren.<br />
Mit einem einfachen quit können Sie diese Shell wieder verlassen.<br />
Eigene Benutzer<br />
Um keine Verwirrung aufkommen zu lassen, möchten wir noch erwähnen, dass<br />
MySQL, wie viele andere komplexe Serverdienste auch, eine eigene Benutzerverwaltung<br />
besitzt. Die Usernamen und Passwörter sind also völlig getrennt von denen<br />
der auf Ihrem System konfigurierten Unix-Accounts.<br />
MySQL kann nicht nur mit unterschiedlichen Benutzern umgehen, sondern ihnen<br />
auch verschiedene Rechte gewähren. Der Datenbankadministrator heißt wie unter<br />
Unix üblich root. Wie bereits gesagt, hat er jedoch nichts mit dem Unix-root zu<br />
tun, und demzufolge hat er meistens auch ein anderes Passwort, das entweder bei<br />
der Paketinstallation gesetzt wurde oder aber »leer«, also nicht vorhanden, ist. 4<br />
19.2.2 SQL<br />
Nachdem man sich mittels mysql mit der Datenbank verbunden hat, stellt sich<br />
die Frage, wie man mit ihr kommuniziert. Zu diesem Zweck gibt es eine von<br />
allen praxisrelevanten relationalen Datenbanken implementierte Sprache: SQL. Mit<br />
ihr kann man auf Datenbanken arbeiten: Tabellen anlegen, Daten einfügen und<br />
löschen sowie natürlich nach bestimmten Tupeln in der Datenbank suchen. Es ist<br />
sogar möglich, bestimmte komplexe Konsistenzbedingungen zu überwachen.<br />
4 Ein Grund mehr, den Datenbankzugriff direkt nach der Installation über das Netzwerk nicht<br />
zu erlauben.<br />
642
MySQL 19.2<br />
Erste Schritte<br />
Um einen ersten Eindruck von SQL zu bekommen, kann man ein paar Standardwerteabfragen,diedasDatenbanksystemauchohnejedevordefinierteTabellebereithält.<br />
Solche Werte sind zum Beispiel das aktuelle Datum sowie die eingesetzte<br />
Version:<br />
mysql> SELECT VERSION(), CURRENT_DATE;<br />
+--------------+--------------+<br />
| version() | CURRENT_DATE |<br />
+--------------+--------------+<br />
| 3.22.20a-log | 2005-12-04 |<br />
+--------------+--------------+<br />
1 row in set (0.01 sec)<br />
Listing 19.20 Einige Werte abfragen<br />
Datenbanken anlegen<br />
MySQL kann natürlich mehr als nur eine Datenbank verwalten. Zu einer Datenbank<br />
gehören in der Regel eine oder mehrere Tabellen, die wiederum bestimmte Spalten<br />
besitzen. Damit unterschiedliche Applikationen, die alle denselben Datenbankserver<br />
benutzen, sich mit ihren Tabellen nicht in die Quere kommen, kann MySQL –<br />
wie eigentlich jedes andere Datenbanksystem auch – mehrere Datenbanken unterscheiden.<br />
Eine neue Datenbank legt man dabei wie folgt an:<br />
Mehrere<br />
Anwendungen<br />
unterstützen<br />
mysql> CREATE DATABASE test;<br />
Listing 19.21 Datenbank anlegen<br />
Diese Datenbank wollen wir nun im Folgenden auch benutzen, was wir mit folgender<br />
Direktive erreichen:<br />
mysql> USE test;<br />
Listing 19.22 Eine bestimmte Datenbank benutzen<br />
Tabellen anlegen und füllen<br />
Eine eigene Tabelle legt man wiederum mit dem Schlüsselwort CREATE an. Beim<br />
Erstellen einer Tabelle muss man auch immer gleich die zugehörigen Spalten samt<br />
ihresTypsundandererAttributwerteangeben:<br />
mysql> CREATE TABLE adressbuch (<br />
-> vorname VARCHAR(25),<br />
-> nachname VARCHAR(25),<br />
-> telefon VARCHAR(15));<br />
Listing 19.23 Eine Tabelle anlegen<br />
643
19 LAMP & Co.<br />
In diesem Beispiel wurde ein einfaches Telefonbuch erzeugt, bei dem jeder Eintrag<br />
einen Vor- und Nachnamen sowie eine Telefonnummer besitzt. Alle Spalten<br />
haben im Beispiel denselben Datentyp: VARCHAR(25) bezeichnet Zeichenketten dynamischer<br />
Länge mit maximal 25 Buchstaben. Das Beispiel ist nicht sonderlich<br />
durchdacht, da es zu unschönen Effekten kommt, wenn zu einer Person beispielsweise<br />
zwei Telefonnummern gespeichert werden sollen. Aber solche Fragen sind<br />
nicht Teil unseres Buches, daher wollen wir nicht näher darauf eingehen.<br />
Stattdessen wollen wir lieber betrachten, wie man Daten in unsere neue Tabelle<br />
einfügen könnte. Dazu muss natürlich der Tabellenname gegeben sein. Außerdem<br />
werden die Werte in der richtigen Reihenfolge der Spaltennamen erwartet:<br />
mysql> INSERT INTO adressbuch<br />
-> VALUES ('Johannes','Plötner','0123/456789');<br />
Listing 19.24 Daten einfügen<br />
Diese kurze Einführung soll als Überblick über die Datenbankerstellung genügen.<br />
Wie immer besteht die Welt <strong>aus</strong> mehr als diesem Buch, so dass wir uns Gott sei<br />
Dank nicht jedem Detail widmen müssen.<br />
Abfragen starten!<br />
Interessant ist jedoch noch die Art und Weise, wie man auf Daten zugreifen kann.<br />
Um Daten abzufragen, wird das SELECT-Statement genutzt. Dazu müssen Sie ein<br />
Kriterium sowie die entsprechende Tabelle angeben. Um sich einfach alles <strong>aus</strong>geben<br />
zu lassen, wird folgendes Statement benutzt:<br />
mysql> SELECT * FROM adressbuch;<br />
+----------+----------+-------------+<br />
| vorname | nachname | telefon |<br />
+----------+----------+-------------+<br />
| Johannes | Plötner | 0123/456789 |<br />
| Maria | Plötner | 123 |<br />
| Steffen | Wendzel | 456 |<br />
+----------+----------+-------------+<br />
Listing 19.25 Alle Daten einer Tabelle<br />
Gezielt suchen<br />
Spannend wird das Ganze aber erst, wenn wir bestimmte Daten gezielt abfragen.<br />
Dazu benutzen wir zusätzlich zu unserem SELECT-Statement eine WHERE-Kl<strong>aus</strong>el:<br />
mysql> SELECT vorname, telefon FROM adressbuch<br />
-> WHERE nachname='Plötner';<br />
+----------+-------------+<br />
| vorname | telefon |<br />
644
PHP 19.3<br />
+----------+-------------+<br />
| Johannes | 0123/456789 |<br />
| Maria | 123 |<br />
+----------+-------------+<br />
mysql> SELECT telefon FROM adressbuch<br />
-> WHERE vorname='Steffen';<br />
+---------+<br />
| telefon |<br />
+---------+<br />
| 456 |<br />
+---------+<br />
Listing 19.26 Gezielte Abfragen<br />
Unsere kleine Einführung in SQL endet hier fürs Erste. Sehen wir uns nun an, wie<br />
dies alles in der Praxis eingesetzt wird. Schließlich wird man dort kaum mit dem<br />
mysql-Tool herumfingern, um an irgendwelche Daten heranzukommen.<br />
19.2.3 APIs<br />
In der Regel möchte man <strong>aus</strong> verschiedenen Programmen her<strong>aus</strong> auf die Funktionalität<br />
von MySQL zugreifen können, anstatt diese Features alle selbst und damit<br />
eine eigene Datenbank zu implementieren. Aus diesem Grund gibt es für jede mindestens<br />
halbwegs relevante Programmiersprache eine SQL-API, über die man auch<br />
mit MySQL sprechen kann.<br />
... und PHP?<br />
Was uns interessiert, ist nun der Zusammenhang mit PHP. Mit diesem wollen wir<br />
uns im nächsten Abschnitt befassen.<br />
19.3 PHP<br />
Auch wenn viele »Informatiker« bei der Frage nach ihren Programmierkenntnissen<br />
die Sprache HTML angeben, so hat die Hypertext Markup Language rein gar nichts<br />
mit Programmierung an sich zu tun. (X)HTML ist eine reine Seitenbeschreibungssprache.<br />
Eine Seitenbeschreibungssprache wie HTML beschreibt nur das Aussehen und die Struktur<br />
von Dokumenten, aber nicht ihr Verhalten.<br />
Mit anderen Worten: Man kann mit HTML zwar sagen, dass ein fett gedruckter<br />
Text neben einem Bild mit grüner Schrift auf blauem Untergrund erscheinen soll,<br />
645
19 LAMP & Co.<br />
jedoch muss man diesen Text bereits bei der Erstellung des Dokuments von Hand<br />
statisch eintragen.<br />
Dynamischer Inhalt<br />
Möchte man den Text dynamisch erstellen und beispielsweise die beim Aufruf<br />
jeweils aktuelle Uhrzeit anzeigen, dann kommen Skriptsprachen wie PHP ins<br />
Spiel. Dazu muss der Webserver selbstverständlich entsprechend konfiguriert sein,<br />
schließlich soll das nun dynamische Dokument zuerst durch einen Parser gejagt<br />
werden, der die Skriptbefehle <strong>aus</strong>wertet und am Ende pures (X)HTML <strong>aus</strong>spuckt.<br />
Diese Ausgabe wird bei jedem Aufruf neu erzeugt, bevor sie schließlich an den<br />
Client geschickt wird.<br />
19.3.1 (X)HTML<br />
Bevor wir uns also den eigentlichen Skriptsprachen widmen, möchten wir ein paar<br />
Worte über (X)HTML verlieren. An erster Stelle steht dabei die Frage, was das X bei<br />
XHTML bedeutet und wo der Unterschied zu HTML liegt.<br />
DieGeschichtevonHTML<br />
Dazu müssen wir uns kurz die Geschichte von HTML in Erinnerung rufen. Die<br />
Sprache wurde 1989 von Tim Berners-Lee und Robert Caillau entwickelt, um mit<br />
dem ebenfalls entwickelten HTTP-Protokoll ein verteiltes Informationssystem für<br />
ihre Arbeit am Kernforschungsinstitut CERN zu erleichtern. Damals wurde HTML<br />
in erster Linie zur Strukturierung von Textdaten gebraucht; Elemente für die Visualisierung<br />
wurden erst später hinzugefügt.<br />
Diese Erweiterungen führten zu bekannten Problemen: Da die Spezifikationen zur<br />
Darstellung anfangs recht ungenau und sogar unvollständig waren, gab es Spielräume<br />
bei der Interpretation von HTML-Seiten. Die dar<strong>aus</strong> resultierenden Unterschiede<br />
in der Darstellung von Webseiten im Internet Explorer oder im Netscape Navigator<br />
führten so manchen Webdesigner bis an den Rand des Suizids.<br />
XML<br />
Später entwickelte man auf Basis des erfolgreichen HTML die Strukturierungssprache<br />
XML. Diese Sprache wurde regelrecht hochgejubelt: man könne mit ihr »alles<br />
machen«! Und das stimmt in gewissem Sinne auch: XML definiert nur, wie ein<br />
Dokument strukturiert sein muss. Es wurden ganze Bücher über dieses Thema<br />
geschrieben, jedoch lässt sich das Wichtigste zu XML in wenigen Sätzen zusammenfassen:<br />
Mit XML strukturiert man seine Daten durch Tags und Attribute. TagskönnenAttribute<br />
enthalten und weitere Tags umschließen. Dazu muss jedem Start-Tag ein schließendes<br />
Tag folgen.<br />
646
PHP 19.3<br />
XHTML ist nun nichts anderes als XML-konformes HTML. Da XML selbst keine<br />
Aussage dazu macht, welche Tags beziehungsweise Attribute erlaubt sind, definiert<br />
man sogenannte Schemata. Und im passenden XHTML-Schema sind eben die für<br />
XHTML vorgesehenen Werte definiert.<br />
HTML »programmieren«<br />
Wie »programmiert« man nun eigentlich HTML? Für einen Einführungskurs eignet<br />
sich am besten die Online-Referenz http://de.selfhtml.org sowie natürlich auch die<br />
Referenz des World Wide Web Consortiums http://www.w3c.org.<br />
Referenzen<br />
<br />
<br />
<br />
Text des Titels<br />
<br />
<br />
Überschrift<br />
Text im Absatz<br />
<br />
<br />
Listing 19.27 Beispiel für eine HTML-Datei<br />
In diesem kleinen Beispiel ist zu erkennen, dass eine Webseite mit der Überschrift<br />
»Überschrift« und einem Absatz mit dem Text »Text im Absatz« erstellt wurde. Die<br />
Tags und sind dabei intuitiv nach der Strukturierung benannt: heading<br />
bedeutet »Überschrift«, und paragraph ist das englische Wort für »Absatz«.<br />
Einige Designrichtlinien<br />
Heutzutage rückt mit XML und dem künftigen Standard XHTML 2.0 die eigentliche<br />
Aufgabe von HTML wieder mehr in den Vordergrund: das Strukturieren des Inhalts.<br />
Die Visualisierung sollte dagegen über CSS-Stylesheets vorgenommen werden.<br />
Für entsprechende Anpassungen eignen sich besonders die -Tags, da diese<br />
kein festgeschriebenes Erscheinungsbild aufweisen und so frei konfiguriert werden<br />
sollen. Vor allem sollte man von einer Layout-Gestaltung mittels Tabellen Abstand<br />
nehmen und auf eben diese divs zurückgreifen. Mit einer solchen Umsetzung des<br />
LayoutshatmaninderRegelauchinexotischenBrowsernkaumDarstellungsprobleme<br />
und trägt sogar zur Barrierefreiheit des Internets bei.<br />
Tabellen versus divs<br />
Einsteiger neigen des Weiteren auch dazu, auf einer »Homepage« alles unterbringen<br />
zu wollen, was sie können oder im Web finden. Bunte, blinkende, mit GIF-Grafiken<br />
überladene Webseiten sind die Folge. Weniger ist da meistens mehr. Und Sie wollen<br />
647
19 LAMP & Co.<br />
doch auch nicht, dass Ihre Webseite <strong>aus</strong>sieht, als sei sie von einem unter Drogen<br />
gesetzten Zehnjährigen entworfen worden.<br />
Jedenfalls gibt es im Netz viele gute Seiten – allen voran natürlich die vom W3C<br />
(www.w3c.org) –, auf denen man viel über Webdesign und die typischen Fehler<br />
lernen kann.<br />
19.3.2 PHP-Support im Apache aktivieren<br />
Modul laden<br />
Bevor wir nun die ersten dynamischen Webseiten programmieren wollen, müssen<br />
wir den PHP-Support im Apache aktivieren. Dazu wird ein spezielles Modul benötigt,<br />
das in der Konfigurationsdatei auch geladen werden will:<br />
$ cat /etc/apache2/mods-enabled/php5.conf<br />
<br />
AddType application/x-httpd-php .php .phtml .php3<br />
AddType application/x-httpd-php-source .phps<br />
<br />
$ cat /etc/apache2/mods-enabled/php5.load<br />
LoadModule php5_module /usr/lib/apache2/modules/libphp5.so<br />
$ grep php /etc/apache2/mods-enabled/dir.conf<br />
DirectoryIndex index.html index.php index.xhtm<br />
Listing 19.28 PHP-Support in Apache 2.x<br />
Ebenfalls müssen die Dateiendungen den entsprechenden MIME-Typen zugeordnet<br />
sowie die Indexdateien definiert werden. Die meisten Distributionen bieten<br />
dafür spezielle Pakete an, die den PHP-Support automatisch zu Ihrem Webbrowser<br />
hinzufügen. So reicht beispielsweise unter Debian folgender Befehl <strong>aus</strong>:<br />
# aptitude install php5 apache2<br />
Listing 19.29 PHP-Apache unter Debian<br />
Anschließend muss der Apache-Server noch über apache2ctl neu gestartet werden.<br />
19.3.3 PHP lernen<br />
Natürlich können wir in diesem Buch keine komplette Einführung in die Programmiersprache<br />
PHP geben; der Verlag Galileo Press hat eigene Bücher zu diesem<br />
Thema publiziert. Einige zum Verständnis notwendige <strong>Grundlagen</strong> möchten wir<br />
jedoch vermitteln.<br />
648
PHP 19.3<br />
PHP ist eine in HTML eingebettete Skriptsprache mit Ähnlichkeiten zu C, Java und Perl. Mit<br />
PHP können dynamisch generierte Webseiten schnell entwickelt werden.<br />
Wie kann man nun PHP nutzen? Betrachten wir dazu ein kleines Beispiel, das zum<br />
Ausprobieren auf unserem PHP-fähigen Apache einfach nur als .php-Datei unterhalb<br />
von DocumentRoot gespeichert werden muss.<br />
<br />
<br />
<br />
PHP-Testseite<br />
<br />
<br />
<br />
<br />
<br />
Listing 19.30 Ein kleines Beispiel für PHP<br />
Man kann gut erkennen, dass PHP wirklich in HTML eingebettet ist. Der echo-Befehl<br />
zur Ausgabe einer Zeichenkette – in unserem Fall ein -Tag samt Text – muss dazu<br />
in eine spezielle Umgebung platziert werden. Bei der Anforderung der Webseite<br />
durch einen Webbrowser wird darum der PHP-Parser den Text zwischen nehmen und als PHP-Code interpretieren. Anschließend wird er den HTML-Code<br />
generieren, der schließlich an den Browser geschickt wird.<br />
Um nun etwas Dynamik in die Sache zu bringen, wollen wir kurz die Auswertung<br />
des folgenden HTML-Formulars betrachten:<br />
...<br />
<br />
Name: <br />
Alter: <br />
<br />
<br />
...<br />
Listing 19.31 Dynamik!<br />
Dieses Formular muss nicht in einer PHP-Datei stehen. Wichtig ist nur, dass das Ziel<br />
dieses Aufrufs ein PHP-Skript ist. Diesem Skript – wie hier der Datei <strong>aus</strong>wertung.php<br />
– werden die Eingaben des Benutzers geschickt, die wie folgt abgerufen werden<br />
könnten:<br />
Formulare<br />
<strong>aus</strong>werten<br />
649
19 LAMP & Co.<br />
...<br />
<br />
Hallo !<br />
Sie sind Jahre alt.<br />
<br />
...<br />
Listing 19.32 Die Eingaben <strong>aus</strong>lesen<br />
Auf die entsprechenden Formulardaten kann über das Array _POST zugegriffen werden.<br />
Variablen werden in PHP durch ein vorangestelltes Dollarzeichen identifiziert<br />
und lassen sich mit echo <strong>aus</strong>geben. Selbstverständlich gibt es bei PHP die Möglichkeit<br />
von Schleifen, Funktionen oder Abfragen von Bedingungen. Aber für einen<br />
ersten Eindruck sollen diese Ausführungen genügen.<br />
Für weitere Informationen sollten Sie die offizielle Webseite www.php.net aufsuchen,<br />
auf der Tutorials, eine Referenz und viele praktische Beispiele zu finden sind.<br />
Abbildung 19.1 PHPMyAdmin<br />
650
PHP 19.3<br />
19.3.4 PHP und MySQL<br />
Natürlich ist PHP auch der Punkt, an dem es an die Nutzung der Datenbank gehen<br />
kann. PHP bietet dafür sogar verschiedene APIs an. Ausführliche Dokumentationen<br />
und Hilfen hierzu gibt es wie immer auf php.net.<br />
Wir wollen uns zunächst einen Anwendungsfall für das Zusammenspiel von PHP<br />
und MySQL ansehen: phpMyAdmin, eine Oberfläche zur Administration einer My-<br />
SQL-Datenbank über das Web.<br />
phpMyAdmin<br />
Für viele Administrationen ist phpMyAdmin (phpmyadmin.net) das Tool der Wahl,<br />
wenn es um die Administration einer MySQL-Datenbank geht. Ein übersichtliches<br />
Webinterface und der große Funktionsumfang machen es möglich.<br />
MySQL-Webadministration<br />
Aber vor allem ist dieses Projekt ein wunderschöner Anwendungsfall, da alle hier<br />
alle Aspekte von LAMP verbunden werden. Auch wenn man selbst keinen eigenen<br />
Webserver mit MySQL und PHP betreibt, kann man mit phpMyAdmin in Berührung<br />
kommen, da viele Webhoster die Software installieren, um ihren Kunden Zugriff<br />
auf deren Datenbanken anzubieten.<br />
Datenbank-Zugriff programmieren<br />
Zum Abschluss dieses Kapitels möchten wir Ihnen noch zeigen, wie Sie von PHP <strong>aus</strong><br />
direkt auf Ihre MySQL-Datenbank zugreifen können. 5 Wir entwickeln zu diesem<br />
Zweck eine HTML-Seite mit PHP-Code. Mit dieser Seite soll es möglich sein, über<br />
Namen von Linux-Befehlen nach deren Zweck zu suchen.<br />
Dazu erstellen wir zunächst eine Datenbank samt Tabelle und loggen uns dazu<br />
zunächst mit dem Datenbank-Benutzer root in die Datenbank ein. Es kann sein,<br />
dass dieser Benutzer auf Ihrem System kein Passwort hat (drücken Sie dazu einfach<br />
bei der Passworteingabe die Enter-Taste), oder dass Sie keinen Benutzernamen<br />
angebenmüssen(gebenSieindiesemFallnurmysql ein).<br />
$ mysql -u root -p<br />
Enter password:<br />
Welcome to the MySQL monitor. Commands end with ; or \g.<br />
Your MySQL connection id is 51<br />
Server version: 5.1.37-1ubuntu5.1 (Ubuntu)<br />
Type 'help;' or '\h' for help. Type '\c' to clear<br />
the current input statement.<br />
5 Für weiteres Know-how zum Thema empfehlen wir Ihnen das ebenfalls bei Galileo Press<br />
erschienene Buch »Einstieg in PHP und MySQL« von Thomas Theis.<br />
651
19 LAMP & Co.<br />
mysql> create database LinuxBefehle;<br />
Query OK, 1 row affected (0,05 sec)<br />
mysql> use LinuxBefehle;<br />
Database changed<br />
mysql> create table befehle (<br />
-> `name` VARCHAR(24) NOT NULL,<br />
-> `bedeutung` VARCHAR(128) NOT NULL );<br />
Query OK, 0 rows affected (0,20 sec)<br />
Listing 19.33 Datenbank und Befehlstabelle erstellen<br />
Abbildung 19.2 Das <strong>aus</strong>geführte PHP-Skript im Browser<br />
Nun füllen wir die Tabelle mit einigen wenigen Beispielbefehlen:<br />
mysql> insert into befehle (`name`,`bedeutung`) VALUES<br />
('ls', 'Listet Dateien in Verzeichnissen auf'),<br />
('echo', 'Gibt Text <strong>aus</strong>'),<br />
('uptime','Zeigt, wie lang ein System bereits laeuft'),<br />
('uname', 'Systeminformationen erfragen');<br />
Query OK, 4 rows affected (0,01 sec)<br />
Records: 4 Duplicates: 0 Warnings: 0<br />
652
PHP 19.3<br />
mysql> quit<br />
Bye<br />
Listing 19.34 Befehlstabelle mit Beispieldaten füllen<br />
Danach erstellen wir ein neues PHP-Skript für die Verarbeitung der Suchanfrage<br />
(das Skript muss test.php heißen, damit das HTML-Formular seine Daten an das<br />
richtige Ziel richtet):<br />
$ cat /var/www/test.php<br />
<br />
<br />
Linux-Befehle<br />
<br />
<br />
<br />
Befehl:
19 LAMP & Co.<br />
/* Ergebnisse abholen und anzeigen */<br />
echo 'Ergebnisse:';<br />
while ($dsatz = mysql_fetch_assoc($res)) {<br />
echo 'Befehl: ' . $dsatz["name"] . "";<br />
echo 'Bedeutung: ' . $dsatz["bedeutung"]<br />
. "";<br />
echo '';<br />
}<br />
/* Verbindung zur Datenbank schließen */<br />
mysql_close($mysql_link);<br />
}<br />
?><br />
<br />
<br />
Listing 19.35 Das PHP-Skript<br />
Im Weiteren erstellen wir eine typische HTML-Seite mit einem Formular, wie Sie<br />
es bereits kennengelernt haben. Mit der PHP-Funktion empty() prüfen wir, ob ein<br />
Wert leer ist oder nicht. Letztlich überprüft die if-Bedingung (grob gesagt), ob der<br />
Formularwert befehl leer ist oder nicht.<br />
Mit der Funktion mysql_connect() verbinden wir uns mit der lokalen Datenbank<br />
mit dem Benutzer $sqluser und dessen Passwort $sqlpass. Diese beiden Werte<br />
müssen Sie in Ihrem Beispiel anpassen. Schlägt die Verbindung fehl, teilt uns dies<br />
die die()-Funktion mit und beendet das Programm.<br />
Um MySQL zu sagen, mit welcher Datenbank wir arbeiten möchten, wählen wir<br />
diese anschließend mit mysql_select_db() <strong>aus</strong>, wozu wir ihren Namen und den<br />
Verbindungs-Link, den wir von mysql_connect() erhalten haben, übergeben.<br />
Der folgende SQL-Befehl holt alle Datensätze <strong>aus</strong> der Tabelle »befehle«, bei denen<br />
der Wert in der Tabellenspalte »name« mit dem Wert, der im Post enthalten ist,<br />
beginnt.<br />
In der while-Schleife holen wir alle Datensätze, die zum Ergebnis des SQL-Befehls<br />
zählen, ab und speichern bei jedem Durchlauf ein Ergebnis im Array $dsatz. Über<br />
dieses (PHP hat assoziative Arrays) können wir einzelne Spalten-Werte des jeweiligen<br />
Datensatzes (etwa den Wert der Spalte »bedeutung«) bequem und einfach<br />
abfragen.<br />
Die Verbindung zum Datenbank-Server wird über die Funktion mysql_close()<br />
geschlossen, der wir zu diesem Zweck die Verbindungsinformationen übergeben.<br />
654
Zusammenfassung 19.4<br />
Bevor Sie Webanwendungen für die Öffentlichkeit entwickeln, sollten Sie sich<br />
mit dem Thema der Sicherheit solcher Webanwendungen befassen. Das gilt nicht<br />
nur für PHP-basierte Webseiten, sondern auch für solche, die in anderen dafür<br />
geeigneten Programmiersprachen bzw. Technologien wie Java Server Pages, Python,<br />
Ruby on Rails, Perl, FastCGI/CGI usw. entwickelt werden. Beim Fachbuchhändler<br />
gibt es mittlerweile recht viele Bücher zu diesem Thema.<br />
19.4 Zusammenfassung<br />
Ein LAMP-Server bietet ein passendes Umfeld für professionelle dynamische Weblösungen.<br />
Linux stellt dabei mit seiner sehr flexiblen Konfiguration die Grundlage für<br />
jedes System dar. Darauf aufbauend wird bei LAMP ein Apache-Webserver aufgesetzt,<br />
der PHP oder eine andere Skriptsprache unterstützt. Über diese Skriptsprache<br />
greift man auf die ebenfalls lokale MySQL-Installation zu.<br />
19.5 Aufgaben<br />
Installation<br />
Installieren und konfigurieren Sie unter Ihrer Lieblingsdistribution ein LAMP-System.<br />
Installieren Sie dazu auch phpMyAdmin.<br />
Webhoster<br />
Stellen Sie sich jetzt vor, Sie hätten eine kleine Firma, die Kunden Webspace mit<br />
PHP- und MySQL-Support zur Verfügung stellt. Wie müssten Sie Ihr System konfigurieren,<br />
damit jeder Kunde z.B. per FTP Zugriff auf seinen Webspace hat und alles<br />
online administrieren kann?<br />
655
Index<br />
(()) 338<br />
*) 345<br />
-FSpot 748<br />
. 222<br />
.. 223<br />
./configure 451<br />
.bmp 744<br />
.class-Datei 932<br />
.exrc 322<br />
.fvwm2rc 724<br />
.gif 744<br />
.jpg 744<br />
.pcx 744<br />
.pdf 744<br />
.png 744<br />
.ps 744<br />
.rhosts 675<br />
.shosts 675<br />
.swf 101<br />
.tga 744<br />
.tiff 744<br />
.xcf 744<br />
.xinitrc 715, 724<br />
.xpm 744<br />
.xsession 707<br />
/bin/ 185<br />
/bin/bash 337<br />
/bin/csh 211<br />
/bin/echo 224<br />
/bin/false 209<br />
/bin/jsh 211<br />
/bin/sh 208, 210<br />
/boot/ 185<br />
/dev 129, 166, 185<br />
/dev/console 842<br />
/dev/dsp 759<br />
/dev/hda 191<br />
/dev/sda 191<br />
/etc/ 185<br />
/etc/adduser.conf 385<br />
/etc/aliases 627<br />
/etc/apt/sources.list 428<br />
/etc/cron.d 455<br />
/etc/cron.daily 455<br />
/etc/cron.monthly 455<br />
/etc/cron.weekly 455<br />
/etc/crontab 455<br />
/etc/default 383<br />
/etc/dhcp.conf 591<br />
/etc/domainname 402<br />
/etc/exports 599<br />
/etc/fstab 172, 423, 473, 896<br />
/etc/group 391, 395<br />
/etc/gshadow 392, 393<br />
/etc/hosts 524<br />
/etc/hosts.allow 586<br />
/etc/hosts.deny 586<br />
/etc/inittab 843<br />
/etc/ldap/slapd.conf 405<br />
/etc/localtime 510<br />
/etc/logrotate.conf 471<br />
/etc/master.passwd 857<br />
/etc/modprobe.conf 501, 502<br />
/etc/modprobe.d 501, 502<br />
/etc/modules 501<br />
/etc/netstart 850<br />
/etc/networks 525<br />
/etc/nsswitch.conf 411, 527<br />
/etc/passwd 379, 382, 385, 857, 1180<br />
/etc/ppp/ 552<br />
/etc/ppp/options 549<br />
/etc/ppp/pap-secrets 552<br />
/etc/rc 849<br />
/etc/rc.conf 849<br />
/etc/resolv.conf 526<br />
/etc/samba/smb.conf 606<br />
/etc/securelevel 852<br />
/etc/services 673<br />
/etc/shadow 380, 387, 857<br />
/etc/shells 213<br />
/etc/skel 384<br />
/etc/ssh/sshd_config 673<br />
/etc/sudoers 398, 399<br />
/etc/syslog.conf 468<br />
/home/ 185<br />
/lib/ 185<br />
/mnt/ 185<br />
/opt 185<br />
/proc/ 186<br />
/proc/swaps 873<br />
/root/ 186<br />
/sbin/ 186<br />
1257
Index<br />
/sbin/lilo 835, 837<br />
/sbin/nologin 209<br />
/tmp/ 186, 421<br />
/usr/ 186<br />
/var/ 187<br />
/var/adm 1111<br />
/var/log 1111<br />
/var/log/Xorg.log 464<br />
/var/log/messages 461, 469<br />
/var/log/wtmp 462, 846, 859<br />
/var/run/utmp 463, 846<br />
/var/spool/cron/crontabs/ 455<br />
; 218<br />
;; 345<br />
343<br />
?-Operator 1015<br />
[] 338<br />
#define 1026<br />
#error 1030<br />
#if 1027<br />
#include 1028<br />
#pragma 1030<br />
#undef 1027<br />
$ 229<br />
$* 229<br />
$0 229<br />
$? 229, 356<br />
$HOME 224, 229, 857<br />
$LOGNAME 229, 857<br />
$MAIL 857<br />
$ORIGIN 659<br />
$PATH 217, 229, 857<br />
$PS1 229<br />
$PWD 229<br />
$RPS1 229<br />
$SHELL 857<br />
$TERM 305<br />
$TTL 659<br />
$$ 229<br />
% (awk-Modulo) 273<br />
&= 337<br />
&& 218<br />
ˆ= 337<br />
\ 219<br />
>n 337<br />
˜ 223<br />
˜- 223<br />
˜/.ssh/authorized_keys 680<br />
˜/.ssh/config 682<br />
˜/.ssh/id_rsa 679<br />
˜/.ssh/id_rsa.pub 679<br />
10base2 520<br />
10baseT 520<br />
1BSD 51<br />
2BSD 51<br />
A<br />
a.out 928<br />
AAAA 660<br />
AbiWord 720<br />
Abstraktion 128<br />
Abweichungen 426<br />
Account 1249<br />
acd0 193<br />
ACL 423<br />
abfragen 425<br />
Arbeitsweise 424<br />
setzen 424<br />
ad0 193<br />
addgroup 392<br />
adduser 383<br />
Adobe 771<br />
Adressen 1032<br />
Adressraum 133, 153<br />
Betriebssystem 161<br />
Codesegment 154<br />
Heap 157<br />
ADSL 553<br />
AfterStep 723<br />
agetty 855, 856<br />
AIX<br />
Partition 829<br />
alias 221, 1203<br />
Alias (C-Shell) 366<br />
Alias-Check 220<br />
alien 440<br />
ALSA 761, 762<br />
Anführungszeichen 233<br />
Anjuta 953<br />
Anonymität 1102<br />
Anwahlskript 552<br />
Apache<br />
access.log 640<br />
apache2.conf 632<br />
apache2ctl 638<br />
error.log 640<br />
1258
Index<br />
Geschichte 632<br />
Logdatei 640<br />
Module 640<br />
PHP 640<br />
PHP-Support 648<br />
usermdir 1187<br />
Virtual Host 636<br />
VirtualHost 1189<br />
apache 631<br />
apache2ctl 638<br />
AppArmor 1116<br />
apple2 911<br />
Application Layer 516<br />
apropos 202, 1203<br />
APT 428<br />
apt-cache 431<br />
apt-get 428<br />
aptitude 433<br />
Arbeitsverzeichnis 194<br />
Archiv 487<br />
ARP 541, 1249<br />
arp 541<br />
ARP-Cache 541<br />
ARPANET 51<br />
Array 339, 1035, 1049<br />
Elementanzahl 340<br />
Elemente löschen 341<br />
Array (C-Shell) 364<br />
aRts 763<br />
as 934<br />
ash 211<br />
Assembler 120, 934<br />
Asymmetrische Verschlüsselung 672<br />
at 458<br />
AT&T 49, 50<br />
atari800 911<br />
Athena-Projekt 687<br />
ATI 702<br />
atq 460<br />
atrm 460<br />
ATTEMPT 587<br />
audacious 763<br />
Audio 758<br />
Ausgabeumlenkung 235<br />
Ausloggen 858<br />
authorized_keys 681<br />
Autoconf 960<br />
Automake 960<br />
Automatisierung 454<br />
at 458<br />
Cronjob 454<br />
Skripts 454<br />
awk 264, 1204<br />
% 273<br />
Anweisung 267<br />
Anweisungsblock 267<br />
ARGC 275<br />
ARGV 276<br />
Array 279<br />
assoziatives Array 280<br />
atan2() 291<br />
bedingte Anweisung 281<br />
BEGIN 268<br />
break 286<br />
Builtin-Funktion 291<br />
continue 286<br />
CONVFMT 276<br />
cos() 291<br />
delete 281<br />
do-while 287<br />
else 284<br />
END 268<br />
ENVIRON 276<br />
exit 292<br />
exp() 291<br />
FILENAME 276<br />
FNR 276<br />
for 288<br />
FS 277<br />
Funktionen 289<br />
if 281<br />
in 280<br />
int() 291<br />
Interpreter 264<br />
Interpreter-Variable 275<br />
Kommentar 270<br />
log() 291<br />
Modulo 273<br />
next 292<br />
NF 277<br />
NR 277<br />
OFMT 278<br />
OFS 278<br />
ORS 278<br />
rand() 291<br />
return 290<br />
RLENGTH 278<br />
RS 279<br />
RSTART 279<br />
Schleifen 284<br />
1259
Index<br />
B<br />
sin() 291<br />
sqrt() 291<br />
srand() 291<br />
String-Funktion 291<br />
SUBSEP 279<br />
Variable 271<br />
Vergleichsoperator 282<br />
while 284<br />
Zeilenumbruch 270<br />
Backticks 233<br />
Backup 487<br />
Strategie 1071<br />
Base 101<br />
bash 212, 335<br />
Autovervollständigung 245<br />
Programmierung 335<br />
Skripte 335<br />
Basilisk II 911<br />
Batch-Job 460<br />
Bayes-Filter 618<br />
bc 306, 339, 1204<br />
scale 307<br />
BCPL 49<br />
Bedingte Anweisung 341<br />
Bedingungen (C-Shell) 368<br />
Befehl<br />
Suche 243<br />
Suche (besser) 244<br />
Teilersetzung 244<br />
vorheriger 243<br />
Befehlsregister 115<br />
Befehlssatz 114<br />
Bell Labs 49, 50<br />
Benevolent Dictator for Life 55<br />
BeOS, Partition 830<br />
bg 796<br />
BibTex 754<br />
Bildbetrachter 747<br />
BIND<br />
Caching 658<br />
forwarders 658<br />
Konfiguration 657<br />
Master Server 658<br />
named.conf 657<br />
Slave-Server 658<br />
Zones 658<br />
BIOS 828<br />
bison 964<br />
BitchX 573<br />
Bitweiser Operator 1005<br />
Blackbox 725<br />
Blacklist 618<br />
blkid 191<br />
Block 865<br />
Bochs 901<br />
boot 843<br />
Bootcode 828<br />
Bootdisk 56<br />
Bootflag 892<br />
Bootloader 68<br />
Bootmanager 830<br />
Bootskripte 847<br />
Bootstrap 127, 181, 827<br />
bootwait 843<br />
Boson 788<br />
Bourne-Again-Shell 212<br />
Bourne-Shell 208, 210<br />
BPMN 745<br />
Brüche (L A TEX) 737<br />
Branch 1022<br />
break 352, 1014<br />
breaksw 371<br />
Browser 103, 558, 564<br />
Bookmark 105<br />
Lesezeichen 105<br />
Tab 105<br />
Webseite durchsuchen 105<br />
Websuche 104<br />
Brutal Chess 787<br />
BSD 46, 1249<br />
BSD-Lizenz 59<br />
BSDi, Dateisystem 830<br />
BSI 1070<br />
btrfs 867<br />
Bugfix 769<br />
Bugs 946<br />
bzcat 491<br />
bzip2 490<br />
C<br />
C 50, 928, 989, 1249<br />
C (Programmiersprache)<br />
– 1003<br />
?-Operator 1015<br />
übersetzen 992<br />
#define 1026<br />
1260
Index<br />
#error 1030<br />
#if 1027<br />
#ifdef 1027<br />
#include 1028<br />
#pragma 1030<br />
#undef 1027<br />
Adresse 1032<br />
Array 1035<br />
bedingte Anweisung 1010<br />
bitweiser Operator 1005<br />
break 1014<br />
case 1014<br />
char 998<br />
Datei 1041<br />
Datentyp 994<br />
Deklaration 994<br />
Dekrement 1003<br />
do-while 1019<br />
double 1000<br />
Einerkomplement 1007<br />
Endlosschleife 1021<br />
fclose() 1044<br />
Felder 1035<br />
FILE 1043<br />
float 1000<br />
fopen() 1043<br />
for 1020<br />
Formatstring 995<br />
fread() 1045<br />
fscanf() 1042<br />
Funktion 1023<br />
Funktionsparameter 1023<br />
fwrite() 1046<br />
goto 1022<br />
Hello, World 991<br />
Hexwerte 997<br />
if 1011<br />
Initialisierung 994<br />
Inkrement 1003<br />
int 996<br />
Klammern 1002<br />
Kommentar 993<br />
logisches ODER 1006<br />
logisches UND 1006<br />
long 999<br />
long double 1000<br />
Modulo 1003<br />
Nachkommastellen 1002<br />
Oktalwert 997<br />
Operator 1001<br />
Operatortabelle 1009<br />
Pointer 1032<br />
Präprozessor 1025<br />
printf() 995<br />
Rückgabewert 1024<br />
Rechnung 1001<br />
scanf() 1041<br />
Schleife 1016<br />
Shift 1005<br />
short 999<br />
signed 996<br />
sizeof 1008<br />
strcpy() 1040<br />
String 1039<br />
strncpy() 1041<br />
struct 1037<br />
Struktur 1037<br />
switch 1014<br />
unsigned 996<br />
Variable 994<br />
Variablennamen 994<br />
Vergleichsoperatoren 1010<br />
Vorrang 1002<br />
while 1016<br />
XOR 1007<br />
Zeichenkette 1039<br />
Zeiger 1032<br />
C++ 928, 1003<br />
C-Shell 211<br />
CA.sh 1098<br />
Cache 117<br />
L1-Cache 117<br />
L2-Cache 118<br />
L3-Cache 118<br />
cal 1204<br />
Calc 98<br />
Call by Reference 1034<br />
Call Graph 944<br />
case 344, 1014<br />
case (C-Shell) 371<br />
cat 336<br />
Catch-all 1077<br />
cd 194, 1205<br />
cd0 193<br />
cdrecord 749<br />
Cedega 902<br />
cfdisk 70, 890, 892<br />
CHAP 547<br />
char 998<br />
Chargen (Dienst) 590<br />
1261
Index<br />
chat-Skript 550<br />
cheese 775<br />
chgrp 419<br />
CHM-Datei 747<br />
chmod 336, 416, 417, 421, 422<br />
chown 418<br />
chroot 1114<br />
chsh 210<br />
CIFS 877<br />
ClamAV 617<br />
CLI 1249<br />
Client 179, 557<br />
Clinton, Bill 50<br />
clisp 934<br />
Codec 767, 768<br />
coldfire 911<br />
colrm 295<br />
column 294<br />
Common Lisp 934<br />
comp 574<br />
Compiler 124, 927, 1249<br />
Completely Fair Scheduler 142<br />
compress 490, 1206<br />
configure 451<br />
CONSOLE (Variable) 846<br />
Container 900<br />
Copy-on-Write 140<br />
Coredump 937<br />
coreutils 425<br />
Covert Channel 1101<br />
Cox, Alan 55<br />
cp 1206<br />
CPAN 1048<br />
CPU 114, 1249<br />
create() 172<br />
cron 454<br />
Cronjob 454<br />
crontab 454, 455<br />
HOME 458<br />
MAILTO 458<br />
PATH 458<br />
SHELL 458<br />
CrossOver 904<br />
csh 211<br />
Alias 366<br />
Array 364<br />
Ausgabeumlenkung 363<br />
Bedingungen 368<br />
Berechnungen 370<br />
breaksw 371<br />
case 371<br />
echo 362<br />
Eingabeumlenkung 363<br />
endsw 371<br />
foreach 370<br />
if 367<br />
Kommentar 362<br />
Pipe 363<br />
Programmierung 361<br />
set 364, 365, 372<br />
Skript 361<br />
switch 371<br />
unset 365<br />
Variablen 364<br />
Werte einlesen 372<br />
while 369<br />
ctrlaltdel 844<br />
CUPS 776<br />
Konfiguration 778<br />
cut 297<br />
cvs 974<br />
commit 975<br />
delete 976<br />
log 977<br />
up 976<br />
CVS_RSH 974<br />
CVSROOT 974<br />
D<br />
Dämonprozess 794, 1249<br />
da0 193<br />
dash 211<br />
Datagramm 516, 585<br />
date 199, 509, 510, 1207<br />
Datei<br />
spalten 303<br />
temporär 357<br />
Dateigröße anzeigen 481<br />
Dateioperation 1041<br />
Dateisuche 300<br />
Dateisystem 474, 863<br />
überprüfen 895<br />
erzeugen 870<br />
formatieren 893<br />
Parameter ändern 894<br />
Dateityp 198, 877<br />
Datenbank 641<br />
Daytime (Dienst) 589<br />
dd 873<br />
1262
Index<br />
DDD 936, 940<br />
DEB-Format 427<br />
Debian 56<br />
stable 56<br />
testing 56<br />
unstable 56<br />
Debugging 936<br />
Default Deny 1076<br />
Default Gateway 531<br />
Dekrement 1003<br />
delgroup 397<br />
deluser 390<br />
depmod 499<br />
Derivat 46<br />
Deskriptor 126, 234<br />
Desktop 704, 713<br />
DeSmuME 911<br />
devfs 166, 875<br />
Device 1249<br />
df 482<br />
dgen 912<br />
dgram 585<br />
dhclient 524, 594<br />
DHCP 523, 591<br />
Client 593<br />
dhcp-client 523, 524, 594<br />
dhcpd 591<br />
dhcpd.conf 591<br />
routers 592<br />
subnet-mask 592<br />
Vergabezeit 592<br />
Dia 745<br />
dict 751<br />
dictd 751<br />
Dienst 583, 588<br />
Chargen 590<br />
Daytime 589<br />
DHCP 591<br />
Discard 589<br />
Echo 589<br />
Finger 590<br />
Netstat 589<br />
QotD 590<br />
Standarddienst 588<br />
Systat 589<br />
Time 589<br />
dig 667, 1208<br />
digiKam 748<br />
Digitalkamera 896<br />
dip 550<br />
disabled 587<br />
Discard (Dienst) 589<br />
DISPLAY 690<br />
distfiles 447<br />
Distribution 46<br />
DivX 767<br />
djbdns 661<br />
DMA-Controller 116<br />
dmesg 1209<br />
DNAT 1078<br />
DNS 1102<br />
AAAA 660<br />
Lookup 663<br />
MX 660<br />
NS 660<br />
PTR 660<br />
Query 663<br />
Server 657<br />
Tools 663<br />
TTL 659<br />
TXT 660<br />
dnscache 661<br />
dnscache-conf 662<br />
do-while 1019<br />
Dock-Apps 723<br />
documentclass 730<br />
Dolphin 88, 717<br />
Dom0 914<br />
Domainname 402<br />
DomU 914<br />
DoS 587<br />
dos2unix 510<br />
DOSBox 909<br />
DOSbox 909<br />
DOSEmu 909<br />
double 1000<br />
dpkg 436<br />
Draw 100, 745<br />
DSL 553<br />
dsniff 1164<br />
du 481<br />
Dual-Head 707<br />
DVD Ländercode 767<br />
DVI-Datei 746<br />
E<br />
E-Mail 613<br />
Server 613<br />
echo 224, 225, 336, 585<br />
1263
Index<br />
echo (C-Shell) 362<br />
Echo (Dienst) 589<br />
Eclipse 953<br />
EcryptFS 876<br />
ed 328<br />
Editor 313<br />
bildschirmorientiert 315<br />
Emacs 323<br />
gvim 322<br />
vi 316<br />
vim 322<br />
X11 740<br />
zeilenorientiert 315<br />
edquota 480<br />
EGID 378<br />
egrep 262, 1210<br />
Einerkomplement 1007<br />
Eingabeumleitung 237<br />
Electric Fence 950<br />
ELF 125, 155, 928<br />
elif 341<br />
Elm 568<br />
else 341, 1012<br />
else if 1012<br />
Emacs 323, 1210<br />
Fenster 325<br />
Kommando 326<br />
Konfiguration 328<br />
Mark 327<br />
Modi 326<br />
Puffer 325, 327<br />
Region 326<br />
Emacs Lisp 934<br />
Embedded-Distribution 47<br />
emerge 446<br />
Emulator 901<br />
Endlosschleife 286, 347, 1021<br />
endsw 371<br />
EOG 747<br />
Epoch 509<br />
Erlang 934<br />
esac 344<br />
esd 763<br />
ESMTP 616<br />
Eterm 693<br />
eth0 519<br />
eth0:1 (virtuelle Schnittstelle) 521<br />
Ethereal 1164<br />
EUID 378<br />
EveryBuddy 748<br />
Evince 746<br />
Ewing, Larry 61<br />
Exec Shield 1117<br />
exec*() 139<br />
exim 620<br />
ACL 621<br />
aliases 627<br />
Mailname 622<br />
Queuerunner 626<br />
Routers 622<br />
Spooling 621<br />
Transports 622<br />
exit 208, 858<br />
exit() 143<br />
explodepkg 445<br />
export 228<br />
expr 339<br />
ext2 866, 1249<br />
ext3 866, 1249<br />
ext4 867, 1249<br />
Extended SMTP 616<br />
Extreme Tux Racer 787<br />
F<br />
Facility 465<br />
false 209, 1210<br />
Fast Filesystem 869<br />
Fastboot 849<br />
FAT12 829<br />
FAT16 829, 877<br />
FAT32 877<br />
fbrun 727<br />
fceu 912<br />
fclose() 1044<br />
fdisk 829, 890<br />
Fedora 57, 1119<br />
Fehler<strong>aus</strong>gabe 234<br />
Fehlerumlenkung 235<br />
Felder 1035<br />
Festplatte 191, 863<br />
Fetchmail 569, 570<br />
FFS 51, 869<br />
fg 796<br />
fglrx 702<br />
fi 341<br />
FIFO 239, 881, 1249<br />
FILE 1043<br />
file 198<br />
File Transfer Protocol 561<br />
1264
Index<br />
find 300<br />
invertierte Suche 302<br />
finger 585<br />
Finger (Dienst) 590<br />
fingerd 1069<br />
Firefox 103<br />
Bookmark 105<br />
Lesezeichen 105<br />
Tab 105<br />
Webseite durchsuchen 105<br />
Websuche 104<br />
Wikipedia 105<br />
Firewall 1075, 1249<br />
fixed-address 593<br />
Flash 771<br />
Flash-Datei 101<br />
Flash-Player 771<br />
Flat Profile 944<br />
Flawfinder 948<br />
flex 964<br />
FlightGear 788<br />
float 1000<br />
Fluxbox 725<br />
Follow-up 574<br />
FooBillard 788<br />
fopen() 1043<br />
for 348, 1020, 1053<br />
foreach 1053<br />
C-Shell 370<br />
fork() 138<br />
Formatieren 486<br />
Formatstring 995<br />
FORTRAN 49, 934<br />
fortune 784<br />
FQDN 527, 1249<br />
Fragmentierung 157, 865<br />
Frame 515<br />
fread() 1045<br />
FreeBSD<br />
Partition 830<br />
Ports 449<br />
Freeciv 786<br />
Freemind 744<br />
Freie Software 58<br />
Freigabe (Windows) 606<br />
fscanf() 1042<br />
fsck 895<br />
FSGID 378<br />
fstab 172, 423, 473, 896<br />
FSUID 378<br />
FTP 561, 671, 1249<br />
Client 561<br />
ftp (Tool) 561, 585<br />
FTP-Server 602<br />
Konfiguration 602<br />
ftpd 602<br />
Funktion 353, 1023<br />
Parameter 355, 1023<br />
Rückgabewert 356<br />
FUSE 868<br />
fuser 1210<br />
FVWM 724<br />
FVWM2 724<br />
FVWM95 724<br />
fwrite() 1046<br />
G<br />
g77 934<br />
GAG 828<br />
gaim 748<br />
gas 934<br />
Gateway 531<br />
gcc 125<br />
Bibliothek 930<br />
ProPolice 1114<br />
Verzeichnisse 929<br />
gdb 937<br />
Breakpoint 938<br />
cont 939<br />
help 940<br />
kill 938<br />
list 938<br />
print 940<br />
run 938<br />
set 939<br />
step 939<br />
GDM 707, 842, 843, 856<br />
gedit 720, 741<br />
General Electric 49<br />
Gentoo 57<br />
Ebuild 446<br />
Hardened 1119<br />
Pakete (Portage) 446<br />
Gerätedatei 163, 881<br />
getfacl 425<br />
getty 183, 855, 856<br />
gftp 563<br />
GID 147, 377, 380<br />
GIMP 743<br />
1265
Index<br />
Git 980<br />
GKsu 710<br />
Gleitkomma-Datentyp 1000<br />
gnbg 912<br />
GNOME 719, 764<br />
Panel 89<br />
gnome-cd 765<br />
GNOME-Shell 91<br />
GNU 52, 58<br />
GNU Chess 785<br />
GNU/Hurd 53<br />
GNU/Mach 53<br />
Gnumeric 720<br />
GnuPG 1104<br />
goto 1022<br />
gpasswd 393, 396<br />
GPG 1103<br />
GPicView 723<br />
GPL 58, 1249<br />
gprof 942<br />
Gqcam 775<br />
Grace-Time 480<br />
Grafikprogramm 743<br />
grep 249, 261, 1212<br />
Filternegierung 262<br />
Greylisting 619, 626<br />
groff 971<br />
groupadd 392<br />
groupdel 397<br />
groups 379, 394<br />
grsecurity 1116<br />
GRUB 494, 828, 1212<br />
GRUB Version 1 831<br />
grub-install 831<br />
GRUB2 833<br />
Gruppenadministrator 394, 396<br />
Gruppenpasswort 393<br />
Gtk 719<br />
GTK+ 983<br />
gunzip 1213<br />
gv 732, 746<br />
gvim 322<br />
Gwenview 747<br />
gzcat 1213<br />
gzip 491, 1213<br />
H<br />
Hacker 1149<br />
halt 842, 859<br />
Hardened Gentoo 1119<br />
Hardlink 879<br />
Hardware<br />
Festplatte 68<br />
Laptops 67<br />
RedHat HCL 67<br />
Unterstützung 65<br />
Hardware-Booten 827<br />
Hardwareuhr 510<br />
Hash 1049<br />
hatari 912<br />
hdparam 889<br />
head 293, 1214<br />
Heap 157<br />
hercules 912<br />
Herunterfahren 827<br />
hexdump 310, 1214<br />
Hintergrundprozess 794, 795<br />
history 242<br />
Hochkomma 234<br />
Hochsprache 124<br />
Home-Verzeichnis 183<br />
Hop 529, 533<br />
host 663, 1215<br />
Hostname 517<br />
hostname 1216<br />
hosts.allow 586<br />
hosts.deny 586<br />
HPFS 829<br />
HTML 646<br />
Design 647<br />
Geschichte 646<br />
htop 804<br />
HTTP 646, 1102, 1249<br />
Telnet 558<br />
Hurd 53<br />
hwclock 510<br />
Hypervisor 899, 913<br />
I<br />
i18n 506<br />
ibmcam 774<br />
ICMP 1102<br />
Iconify 705<br />
ICQ 748<br />
id 395<br />
IDE 952<br />
IDEA 672<br />
IDS 1121<br />
1266
Index<br />
if 341, 1011, 1052<br />
if (C-Shell) 367<br />
ifconfig 518, 535<br />
mehrere Adressen 520<br />
Image viewer<br />
Bildbetrachter 747<br />
IMAP 617<br />
Impress 100<br />
inetd 557, 583, 584, 1069, 1110<br />
internal 586<br />
RPC 584<br />
info 203, 1217<br />
init 138, 140, 183, 827, 841, 842<br />
BSD 849<br />
Runlevel 183<br />
Init-Skript 841<br />
init.d 847<br />
INIT_VERSION (Variable) 846<br />
initdefault 844<br />
inittab 843<br />
Inkrement 1003<br />
INNd 594<br />
Inode 878, 882<br />
insmod 501<br />
Installation<br />
cfdisk 892<br />
OpenBSD 78<br />
Slackware 75<br />
installpkg 442<br />
Instant Messenger 748<br />
int 996<br />
Integer-Variablen 337<br />
Integral (L A T E X) 737<br />
Internet Layer 515<br />
Internetzugang 545<br />
Interpreter 124, 927, 1249<br />
Interrupt 119, 124, 141, 161<br />
Intrusion Detection System 1121<br />
ioctl.save 842<br />
IPC 144, 147, 793, 1249<br />
IPC im Dateisystem 881<br />
IPP 779<br />
iptables<br />
ACCEPT 1081<br />
DROP 1081<br />
filter 1083<br />
LOG 1082<br />
mangle 1083<br />
NAT 1086<br />
nat 1083<br />
QUEUE 1081<br />
Referenz 1080<br />
REJECT 1082<br />
RETURN 1081<br />
IPv6 1102<br />
IPv6-Support 584<br />
ipw2200 522<br />
IRC 573, 749<br />
Client 573<br />
Irssi 755<br />
ISC 657<br />
ISDN 57<br />
ISO 9660 869, 1249<br />
IT-Grundschutz 1070<br />
iwconfig 523<br />
iwlist 522<br />
J<br />
JabRef 754<br />
jail 900<br />
Java 113, 125, 744, 754, 931<br />
javac 932<br />
JFS 867<br />
Job-ID 794<br />
Job-Shell 211<br />
jobs 797<br />
journal 866<br />
Journaling 866, 1250<br />
Joy, Bill 51<br />
jsh 211<br />
Jump 1022<br />
K<br />
K-Menü 86<br />
K3b 749<br />
KAME 584<br />
Karbon14 102<br />
Kate 741<br />
kbrequest 844<br />
KChart 103<br />
kchmviewer 747<br />
KCron 718<br />
kdbcontrol 508<br />
kdbmap 508<br />
KDE 85, 713, 764<br />
beenden 715<br />
Konsole 693<br />
starten 715<br />
1267
Index<br />
System Settings 716<br />
Tastenkürzel 716<br />
KDE su 710<br />
KDevelop 718, 953<br />
KDM 707, 843, 856<br />
kdump 945<br />
Keep 718<br />
Kernel 113, 122, 127, 1250<br />
<strong>Grundlagen</strong> 114<br />
Hardening 1114<br />
installieren (BSD) 498<br />
kompilieren 492, 494<br />
kompilieren (BSD) 495, 497<br />
konfigurieren 493<br />
Logging 466<br />
Modul 163, 1110, 1250<br />
Ringpuffer 1209<br />
Version 492<br />
Kernel Virtual Machine 919<br />
Kernelspace 1250<br />
Kernelstack 161<br />
Kernighan, Brian 49<br />
Kexi 103<br />
Keyserver 1109<br />
KFormula 103<br />
kill 800, 1217<br />
killall 810, 811, 1218<br />
KitchenSync 103<br />
Kivio 101<br />
klogd 466<br />
KLT 136<br />
KMail 103, 568<br />
KMenuEdit 716<br />
KMix 764<br />
KNode 578<br />
Knode 103<br />
Knopper, Kl<strong>aus</strong> 57<br />
Knoppix 57<br />
Knotenpunkt 529<br />
KNotes 719<br />
KOffice 101, 717<br />
Kommando-History 242<br />
Kommandogruppe 241<br />
Kommandosubstitution 232<br />
Anführungszeichen 233<br />
Backticks 233<br />
Hochkomma 234<br />
Kommentar 337<br />
Kommentar (C-Shell) 362<br />
Komprimierung 426, 489<br />
Konqueror 717<br />
Kontact 103<br />
Kontextwechsel 158<br />
Kontrollblock (Thread) 148<br />
KOrganizer 103<br />
Korn-Shell 211<br />
KPDF 746<br />
KPhotoAlbum 748<br />
KPIM 101<br />
kpm 719<br />
kppp 545<br />
KPresenter 101<br />
Krita 102<br />
KsCD 765<br />
ksh 211<br />
KSpread 101<br />
KSquirrel 747<br />
KsystemLog 718<br />
ktrace 945<br />
Kugar 103<br />
KVM 919, 922<br />
QEMU 920<br />
Kword 101<br />
KWordQuiz 753<br />
KWrite 719<br />
L<br />
l10n 506<br />
Label 1022<br />
LAMP 631<br />
LANG 508<br />
langdrill 753<br />
lastlog 462<br />
L A T E X 729, 754<br />
Abschnitte 734<br />
article 730<br />
Auflistungen 735<br />
author 734<br />
book 730<br />
chapter 734<br />
emph 734<br />
Fettschrift 734<br />
Inhaltsverzeichnis 734<br />
itemize 735<br />
Kapitel 734<br />
Kursivschrift 734<br />
letter 730<br />
Listing 735<br />
maketitle 734<br />
1268
Index<br />
Mathematik 736<br />
newpage 734<br />
Package 731<br />
report 730<br />
section 734<br />
textbf 734<br />
title 734<br />
verbatim 735<br />
L A T E X<br />
Bilder 738<br />
Kommentar 739<br />
Literaturverzeichnis 738<br />
latex2html 730<br />
Laufwerk 191<br />
Laufzeitumgebung 902<br />
LC_ALL 509<br />
ld 935<br />
LDAP 403<br />
dc 405<br />
dn 405<br />
Objektklasse 405<br />
Schema 405<br />
ldapadd 408<br />
ldapmodify 408, 409<br />
Leafpad 723<br />
less 197<br />
LessTif 982<br />
let 338<br />
lex 964<br />
Lexikalische Analyse 964<br />
libc 126, 985<br />
libefence 950<br />
libmpeg2 985<br />
libpcap 542<br />
libpng 985<br />
LibreOffice 93<br />
Draw 745<br />
libstdc++ 985<br />
libtar 986<br />
Libtool 960<br />
LibUnicode 985<br />
libUSB 985<br />
libXML2 985<br />
Liferea 580<br />
LILO 828, 835<br />
lilo (Programm) 835<br />
lilo.conf 835<br />
lilo 1218<br />
Limes (L A T E X) 737<br />
Link-Count 880<br />
Link-Layer 515<br />
Linken 935<br />
Links (Dateisystem) 879<br />
Links (Web-Browser) 564<br />
Linux 46<br />
Lisp 934<br />
Listen-Ports 540<br />
LKM 1110, 1113, 1250<br />
ln 879, 1219<br />
lo 519<br />
Loadable Kernel Modules 1113<br />
loadkeys 506<br />
lockd 599<br />
log_on_failure 587<br />
log_on_success 587<br />
Logarithmus (L A TEX) 737<br />
logcheck 472<br />
Logdateien 461<br />
logger 359, 1219<br />
Logging 461, 1068<br />
Login 183<br />
grafisch 706<br />
login 857<br />
Login-Shell 209, 857<br />
Login-Versuch 462<br />
LoginGraceTime 674<br />
Logisches ODER 1006<br />
Logisches UND 1006<br />
Loglevel 465<br />
logout 208, 858<br />
logrotate 471<br />
Lokalisierung 506<br />
long 999<br />
long double 1000<br />
Long Time Support 57<br />
Loop-Device 870<br />
Loopback 641<br />
LP-Tools 776<br />
lpq 777<br />
lpr 777<br />
lprm 777<br />
lpq 777<br />
lpr 777<br />
lprm 777<br />
ls 196, 415, 1220<br />
lsmod 500<br />
lspci 66, 760<br />
LTS (Long Time Support) 57<br />
Lua 934<br />
LVM 482<br />
1269
Index<br />
LXDE 722<br />
lynx 564<br />
M<br />
Mac OS X<br />
Partition 830<br />
mac2unix 510<br />
Mach 53<br />
mail (Konsolenprogramm) 565<br />
mail (Tool) 565<br />
Mail-Exchanger 660<br />
Mailname 622<br />
Mailprogramme 565<br />
mailq 626<br />
Make 954<br />
make 452, 1221<br />
Aufruf 959<br />
clean 959<br />
install 959<br />
Makefile 955<br />
Makros 958<br />
Shellvariablen 959<br />
Suffixregeln 957<br />
Target 955<br />
makepkg 445<br />
Makros 1026<br />
malloc() 130<br />
man 200, 1222<br />
Mandatory Access Control 1118<br />
Mandrake 57<br />
Mandriva 57<br />
Manpage 200, 1222<br />
erstellen 970<br />
Mantisse 1000<br />
Maschinensprache 114<br />
Masquerading 1078<br />
Master Boot Record 828<br />
Math 100<br />
Mathematische Zeichen 736<br />
max-lease-time 592<br />
MBR 182, 828<br />
McDonald, Peter 56<br />
mdadm 485<br />
Mehrzeiliges Kommando 219<br />
Menü erstellen 351<br />
Mengensymbol (L A T E X) 736<br />
menu.1st 832<br />
Message Queue 819<br />
Metadaten 427<br />
Metrik 533<br />
Microkernel 53<br />
mingetty 855, 856<br />
Minix, Dateisystem 829<br />
misc 574<br />
mke2fs 896<br />
mkfifo 1222<br />
mkfs 893, 1195<br />
mkisofs 749<br />
mkreiserfs 896<br />
mkswap 873<br />
mktemp 357<br />
MLS 1101<br />
MMU 151<br />
Modems 548<br />
modinfo 500<br />
modprobe 499<br />
modules.dep 499<br />
Modulo 1003<br />
Monitoring 1121<br />
more 197, 238<br />
most 197<br />
Motif 982<br />
Motion 775<br />
mount 477, 486<br />
mountd 599<br />
Mounting 172<br />
Mozilla 568<br />
Mozilla Firefox 103<br />
MP3-Player 757, 763, 896<br />
mplayer 768<br />
mtree 1118<br />
Multiboot 68<br />
MULTICS 49<br />
Multilevel Undo/Redo 315<br />
Multiline Kommando 219<br />
Multimedia 757<br />
Audio 758<br />
Video 766<br />
Multiple Document Editing 315<br />
Multitasking 115, 129, 1250<br />
Multiuser 1250<br />
Multiuser-Modus 842<br />
Murdock, Ian 56<br />
Mutt 568<br />
mv 1223<br />
MX 660<br />
MX-Record 616<br />
MySQL 641<br />
Administration 641<br />
1270
Index<br />
N<br />
Datenbank anlegen 643<br />
my.cnf 641<br />
mysql 641<br />
Tabelle anlegen 643<br />
Nagios 1135<br />
Hostgruppen 1143<br />
Hostobjekte 1142<br />
Installation 1137<br />
Kommandos 1146<br />
Konfiguration 1140<br />
Kontakte 1145<br />
Kontaktgruppen 1145<br />
Plugins 1138, 1147<br />
Serviceobjekte 1144<br />
named 1224<br />
Start 660<br />
Named Pipe 239, 881, 1193<br />
named.conf 657<br />
NASM 934<br />
NAT 1078<br />
ncurses 982<br />
NEdit 741<br />
nestra 912<br />
Net/1 51<br />
NETBIOS 528<br />
NetBSD 52<br />
Partition 830<br />
Ports 447<br />
netconfig 522<br />
nethack 783<br />
netpkg 441<br />
netstat 529, 535<br />
Netstat (Dienst) 589<br />
Network Access Layer 515<br />
Network File System 598<br />
Netzwerk<br />
Setup 517<br />
Netzwerk-Scanner 1122<br />
Netzwerkverbindung 535<br />
newgrp 394<br />
news 574<br />
Newsfeed 579<br />
Newsgroup 573<br />
NeXTSTEP<br />
Partition 830<br />
NFS 180, 598, 1250<br />
async 600<br />
Client 601<br />
Dateisystem 875<br />
dev 601<br />
exec 601<br />
exports 599<br />
Netzmaske 600<br />
nodev 601<br />
noexec 601<br />
nosuid 601<br />
nouser 601<br />
Server 599<br />
suid 601<br />
sync 600<br />
user 601<br />
Wildcard 600<br />
nfsd 599<br />
nice 813<br />
NIS 400<br />
nl 293, 1224<br />
Nmap 1149<br />
Praxis 1158<br />
nmbd 606<br />
NNTP 575, 1102, 1250<br />
ARTICLE 576<br />
Client 577<br />
GROUP 576<br />
HELP 576<br />
LIST 576<br />
POST 576<br />
QUIT 576<br />
Server 594<br />
nologin 209<br />
nowait 585<br />
NRPE 1149<br />
NRU 1102<br />
NS 660<br />
NSCA 1149<br />
nslookup 665<br />
nsswitch.conf 527<br />
NTFS 475, 829, 877<br />
NTP 572<br />
ntpdate 572<br />
Nullmodem 548<br />
Nullmodemkabel 547<br />
NVIDIA 702<br />
NWD 1101<br />
1271
Index<br />
O<br />
O(1)-Scheduler 141<br />
OASIS 93<br />
Oberfläche 687<br />
objdump 155<br />
Objektdatei 928<br />
od 310, 1225<br />
off (init) 844<br />
Offenes Relay 615<br />
Oktalzahl 416<br />
Okular 746<br />
once 843<br />
ondemand (init) 844<br />
only_from 587<br />
Open Source 1250<br />
open() 170, 172<br />
Open-Source 769<br />
Openbox 723<br />
OpenBSD 1118<br />
Installation 78<br />
Partition 830<br />
Ports 448<br />
OpenLDAP 405<br />
OpenMortal 786<br />
OpenMotif 982<br />
openntpd 572<br />
OpenOffice.org 93<br />
Base 101<br />
Calc 98<br />
Draw 100, 745<br />
Impress 100<br />
Math 100<br />
OpenPAM 1118<br />
OpenSSH 671<br />
Konfiguration 673<br />
OpenSSL 1098<br />
openSUSE 71<br />
OpenVPN 1095<br />
Client 1101<br />
Konfiguration 1099<br />
Roadwarrior-Setup 1099<br />
Server 1099<br />
Openwall 1116, 1119<br />
Orange 722<br />
ordered 867<br />
Orthogonalität 180<br />
OSS (Open-Sound-System) 759, 762<br />
OWL 1116, 1119<br />
P<br />
p7zip 491<br />
Page Fault 152<br />
Pager 197<br />
Pagetable 150<br />
Paging 149<br />
Pakete 425<br />
konvertieren 440<br />
Paketmanagement 59, 427<br />
Metadaten 427<br />
palimpsest 885<br />
PAM 410, 411<br />
PAP 547<br />
Parameter 355<br />
Paravirtualisierung 900<br />
Partitionstabelle 829<br />
Partitionstyp(en) 829<br />
pase 297<br />
passwd 387, 420<br />
paste 297, 1225<br />
Patch 55<br />
PATH 437, 846<br />
erweitern 335<br />
PaX 1117<br />
PCAP 542<br />
pcap 985<br />
pcsx 912<br />
PCT (Protocol Channel Tool) 1102<br />
PDF-Datei 746<br />
pdf2ps 1192<br />
pdflatex 732, 1192<br />
pdftohtml 263<br />
pdftops 263<br />
pdftotext 263<br />
pdksh 211<br />
PDP-11 50<br />
pearpc 912<br />
Peers 546<br />
Perfect Forward Secrecy 1096<br />
Perl 930, 1047<br />
close 1064<br />
CPAN 1048<br />
Datei lesen 1063<br />
Datei schreiben 1063<br />
for 1053<br />
foreach 1053<br />
if 1052<br />
Kontrollstruktur 1052<br />
m 1060<br />
1272
Index<br />
Modul 1047<br />
open 1062<br />
regulärer Ausdruck 1059<br />
s 1060<br />
Subroutine 1057<br />
TIMTOWTDI 1055<br />
tr 1062<br />
Typisierung 1050<br />
unless 1055<br />
until 1055<br />
Variable 1049<br />
while 1054<br />
perldoc 931<br />
Personal Firewall 1077<br />
PGP 1103<br />
pgrep 810<br />
PHCCT 1102<br />
PHP 645, 648<br />
MySQL 651<br />
phpldapadmin 407<br />
π (L A T E X) 738<br />
PID 137, 146<br />
Pidgin 748<br />
pidof 810, 1226<br />
Pine 568<br />
ping 541<br />
Ping Tunnel 1102<br />
Pipe 238<br />
Ausgabe duplizieren 239<br />
Pipe (C-Shell) 363<br />
pipe() 815<br />
pkgsrc 447<br />
pkgtool 442<br />
pkill 810<br />
Pointer 1032<br />
Pool (btrfs) 867<br />
Pool (ZFS) 867<br />
POP3 617, 1102<br />
poppler-utils 263<br />
Port 59<br />
Port-Management 450<br />
FreeBSD 449<br />
NetBSD 447<br />
OpenBSD 448<br />
portmap 400, 1069<br />
Ports 426, 427, 446<br />
Ports Collection 449<br />
Portscan<br />
Bannerscanning 1157<br />
Fingerprinting 1158<br />
Fragmentierungsscan 1153<br />
Reverse Ident Scan 1153<br />
TCP Connect Scan 1151<br />
TCP Fin Scan 1152<br />
TCP Idle Scan 1153<br />
TCP Null Scan 1152<br />
TCP Syn Scan 1151<br />
UDP Scan 1156<br />
Portscanner 1149<br />
Portstree 448<br />
Posting 574<br />
powerfail 844<br />
powerfailnow 844<br />
poweroff 859<br />
powerwait 844<br />
powerwaitok 844<br />
PPP 546<br />
Anmeldung 546<br />
Anwahlskript 552<br />
CHAP 547<br />
chat 550<br />
DSL 553<br />
Einwahl 552<br />
Modem 548<br />
options 549<br />
PAP 547, 552<br />
pppd 547<br />
PPPoE 553<br />
Trennung 552<br />
pppd 547<br />
chat-Skript 550<br />
Konfiguration 549<br />
pap-secrets 552<br />
PPPoE 553<br />
pppoeconf 554<br />
PPRacer 787<br />
Präprozessor 992, 1025<br />
Pre-shared Key 1096<br />
printf() 464, 995<br />
printf() (C) 995<br />
ProcFS 875<br />
Procmail 570, 571<br />
Produktsymbol (L A T E X) 737<br />
Profiling 942<br />
proftpd 602<br />
Programm 115<br />
PROM 827<br />
PROMISC-Flag 544<br />
Prompt 193, 207, 229<br />
ProPolice 947, 1114<br />
1273
Index<br />
Protokoll 513<br />
Protokollstatistik 536<br />
Proxy<br />
Squid 1091<br />
transparent 1090<br />
Proxyserver 1088, 1250<br />
Prozess 132, 145, 793, 1250<br />
Ende 142<br />
Erstellung 138<br />
interaktiv 141<br />
jobs 797<br />
Priorität 141, 811<br />
rechenintensiv 141<br />
Prozessart 794<br />
Prozessgruppe 241<br />
Hintergrund 242<br />
Prozesshierarchie 140, 146<br />
Prozessor 114<br />
Befehlssatz 114<br />
Register 115<br />
Ringe 120<br />
Prozessstatus 808<br />
Prozesstabelle 145, 805<br />
ps 808<br />
PS-Datei 746<br />
ps2pdf 730<br />
pscan 948<br />
Pseudo-Dateisystem 875, 1250<br />
pstree 805<br />
PTR 660<br />
pulseaudio 763<br />
PULT 136<br />
PuTTY 676<br />
pwd 194, 1227<br />
Python 934<br />
Q<br />
QEMU 920<br />
QNX<br />
Partition 829<br />
QotD (Dienst) 590<br />
Qt 983<br />
Quake 782<br />
Quanta+ 954<br />
Queuerunner 626<br />
quiz 753<br />
Quota 478, 1250<br />
aktivieren 478<br />
edquota 480<br />
Grace-Time 480<br />
setzen 479<br />
quota (Tool) 480<br />
Quota-Support 478<br />
quotaoff 479<br />
quotaon 479<br />
qwertz 506<br />
R<br />
R-Dienst 590<br />
R-Tools 560, 671<br />
Rückgabewert 1024<br />
RAID 483<br />
Level 0 483<br />
Level 1 483<br />
Level 5 483<br />
RAM 1250<br />
Ramdisk 485, 872<br />
range 592<br />
rar-Archiv 491<br />
RATS 948<br />
rc.d 847<br />
rcp 560<br />
read 227, 1227<br />
read() 172<br />
readdir() 172<br />
readline 985<br />
readonly 228<br />
reboot 859<br />
reboot (Runlevel) 843<br />
rec 574<br />
Rechner<br />
bc 306<br />
Rechtemaske 416<br />
Rechteverwaltung 188, 415<br />
Eigentümer ändern 418<br />
Gruppe ändern 419<br />
Rechte ändern 416<br />
Sticky-Bit 421<br />
umask 422<br />
recode 510<br />
RECORD 587<br />
Record<br />
Siehe Struktur 1037<br />
Red Hat 57<br />
Redundanz 177<br />
regex 249, 1059<br />
Register 115<br />
Reguläre Datei 878<br />
1274
Index<br />
Regulärer Ausdruck 249, 265, 618, 1059<br />
(xyz) 260<br />
{xyz} 261<br />
Aufbau 251<br />
Geschwindigkeit 262<br />
Wiederholung 260<br />
ReiserFS 867, 1250<br />
Relativer Pfad 217<br />
Relay (SMTP) 615<br />
Remote-Logging 470<br />
removepkg 443<br />
renice 813<br />
Repository 427<br />
Resident Set 158<br />
respawn 843<br />
Ressourcenverwaltung 132<br />
Restricted Shell 1112<br />
return (Funktionen) 356<br />
Reverse Proxy 1090<br />
rexec 560<br />
RGID 378<br />
Ringpuffer 1209<br />
Ristretto 722, 747<br />
Ritchie, Dennis 50<br />
rksh 1113<br />
rlogin 560<br />
rmmod 501<br />
ROM 1250<br />
root 189, 378, 387, 397, 674<br />
Rootdisk 56<br />
route 530, 532, 533<br />
Router 531<br />
Routers (Exim) 622<br />
Routing 529<br />
Routing-Tabelle 529<br />
Routing-Tabelle 529<br />
RPC 401, 599<br />
rpc.lockd 599<br />
rpc.mountd 599<br />
rpc.statd 599<br />
rpcinfo 403<br />
RPM 57<br />
rpm 440<br />
RPM-Format 427<br />
RSA 672<br />
RSBAC 1119<br />
rsh 560<br />
RSS 579<br />
Ruby 934<br />
RUID 378<br />
Rule Set Based Access Control 1119<br />
Runlevel 183, 841, 842, 845, 846<br />
ondemand 844<br />
Skript 841<br />
runlevel (Programm) 846<br />
RUNLEVEL (Variable) 846<br />
S<br />
S/MIME 1103, 1110<br />
Samba 528, 605, 877<br />
LDAP 610<br />
SANE 780<br />
Sauerbraten 787<br />
scanf() 1041<br />
SCHED_OTHER 812<br />
Scheduler 140<br />
CFS 142<br />
O(1)-Scheduler 141<br />
Scheduling 119, 140, 811<br />
kooperativ 160<br />
Scheme 934<br />
Schleife 346, 1016<br />
Schleifenabbruch 352<br />
sci 574<br />
scp 1228<br />
script 310, 1228<br />
scriptreplay 1229<br />
ScummVM 907<br />
sd0 192<br />
SDL 762<br />
SEBSD 1116<br />
Secondary Boot 828<br />
Secure Copy 677<br />
Secure Shell 671<br />
Securelevel 852<br />
security through obscurity 1078<br />
sed 253, 1230<br />
(Ausdruck) 260<br />
{Ausdruck} 261<br />
Befehle 255<br />
Befehlsliste 256<br />
Holdspace 256<br />
Patternspace 256<br />
s-Befehl 258<br />
w-Befehl 257<br />
Wiederholung 260<br />
y-Befehl 258<br />
Zeilenfilter 259<br />
Seitenbeschreibungssprache 645<br />
1275
Index<br />
select 351<br />
SELinux 1116<br />
Semaphore 817<br />
Sender Policy Framework 616<br />
seq 1230<br />
Server 179, 583<br />
set 227<br />
setfacl 424<br />
SetGID-Flag 420<br />
setuid() 420<br />
SetUID-Flag 420<br />
SFTP 676<br />
SGID 378<br />
sh 210<br />
Shared Libraries 934<br />
Shared Memory 822<br />
Shell 178, 207, 585<br />
Array 339<br />
bc in Pipe 339<br />
beenden 858<br />
Editor 313<br />
EDITOR (Variable) 334<br />
Funktion 353<br />
Integer-Variable 337<br />
Kommentar 337<br />
Menü erstellen 351<br />
Prompt 193, 207, 229<br />
rechnen 337<br />
Startvorgang 857<br />
Variable 225<br />
verlassen 858<br />
Shellprozess 795<br />
Shellskript 336<br />
Shellskriptprogrammierung 335, 361<br />
Shiften 1005<br />
short 999<br />
Shotwell 748<br />
showmount 601<br />
shsh 211<br />
shutdown 845, 859, 1231<br />
Shutdown (Vorgang) 128, 858<br />
Sicherheit 1067<br />
Benutzerrechte 1068<br />
Logging 1068<br />
Netzwerkdienste 1068<br />
SIGALRM 801<br />
SIGCONT 801<br />
SIGHUP 801<br />
SIGKILL 144, 801<br />
Signal 144, 799<br />
signed 996<br />
SIGSTOP 801<br />
SIGTERM 144, 801<br />
simh 912<br />
Single-User-Modus 842<br />
sizeof 1008<br />
Skalar 1049<br />
Skalierbarkeit 180<br />
Skript-Interpreter 337<br />
slackpkg 441<br />
Slackware 56<br />
Installation 75<br />
Packages 441<br />
slapt-get 441<br />
sleep 359, 1231<br />
Slice 193<br />
slrn 577<br />
SLS 56<br />
Smalltalk 934<br />
Smarthost 615<br />
SMB 877, 1250<br />
smb.conf 606<br />
smbd 606<br />
SMTP 613, 1102, 1250<br />
SMTP-Server 620<br />
SNAT 1078<br />
sndconfig 760<br />
Sniffer 1162<br />
Sniffing 542<br />
snort 1122<br />
config 1128<br />
Installation 1122<br />
preprocessor 1130<br />
Sniffer 1123<br />
Snownews 579<br />
SOA 659<br />
Expire 660<br />
Refresh-Number 660<br />
Retry-Number 660<br />
Serial-Number 660<br />
TTL 660<br />
soc 574<br />
SOCK_DGRAM 585<br />
SOCK_STREAM 585<br />
Sockets 824, 881<br />
Soft Landing System 56<br />
softgun 912<br />
Softlink 879<br />
SoftRAID 482<br />
konfigurieren 484<br />
1276
Index<br />
mdadm 485<br />
SoftUpdates 869<br />
Softwareinstallation 425<br />
Solaris 900<br />
Partition 830<br />
Trusted Solaris 1118<br />
sort 298, 1232<br />
Sound 762<br />
sox 766<br />
Spam 617<br />
SpamAssassin 617<br />
spectemu 912<br />
Speicher 115, 116<br />
Hierarchie 117<br />
Wort 116<br />
Speichermanagement 149<br />
Speicherzugriffsfehler 130, 152<br />
SPF 616<br />
Spiele 757, 781<br />
SPIM 912<br />
split 303, 1232<br />
Spooling 132, 181<br />
Spooling (exim) 621<br />
sprayd 585<br />
SQL 642<br />
DATABASE 643<br />
INSERT 644<br />
SELECT 644<br />
TABLE 643<br />
Squid 1091<br />
Konfiguration 1092<br />
SSH 560, 671<br />
Port-Forwarding 682<br />
Protokoll 1 672<br />
Protokoll 2 672<br />
Public-Key-Login 678<br />
Remote-Login 676<br />
Root-Login 674<br />
scp 677, 680<br />
Secure Copy 677<br />
Secure File Transfer 681<br />
Serverkonfiguration 673<br />
sftp 676, 681<br />
ssh 676<br />
Tunnel 682<br />
X11 Forwarding 676, 681<br />
ssh 1233<br />
SSL 640<br />
Stack 133, 134, 158<br />
Stack Smashing Protection 1117<br />
Stallman, Richard 52<br />
Standalone 584<br />
Standard<strong>aus</strong>gabe 234<br />
Standardeingabe 234<br />
StarDict 751<br />
startkde 715<br />
Startleiste 706<br />
statd 599<br />
State-Regel 1076<br />
STDERR 234<br />
STDIN 234<br />
STDOUT 234<br />
Steganografie 1101<br />
stella 912<br />
Sticky-Bit 421<br />
strace 945<br />
strcpy() 1040<br />
stream 585<br />
Strg + D 858<br />
Strings 1039<br />
<strong>aus</strong>geben 1040<br />
kopieren 1040<br />
vergleichen 344<br />
strncpy() 1041<br />
struct 1037<br />
Struktur 1037<br />
su 397<br />
Subroutine (Perl) 1057<br />
Subshell 241, 1250<br />
Subversion 978<br />
Subvolumes (btrfs) 867<br />
Suchen (Datei) 300<br />
sudo 398<br />
/etc/sudoers 399<br />
SUID 378<br />
sulogin 842<br />
Summenzeichen (L A T E X) 736<br />
SuperTux 787<br />
SUSE 71<br />
SVR4<br />
Geschichte 50<br />
init 841<br />
Swap 872, 1250<br />
Verschlüsselung 874<br />
Swap-Datei 873<br />
swapon 873<br />
Swapping 150<br />
SWF-Datei 771<br />
switch 1014<br />
switch (C-Shell) 371<br />
1277
Index<br />
Sylpheed 578<br />
sylpheed 568<br />
Symbolischer Link 879<br />
Symmetrische Verschlüsselung 672<br />
sync 600, 1234<br />
Syntax-Analyse 964<br />
Syntax-Highlighting 314<br />
Syscall 121, 122, 130, 1250<br />
create() 172<br />
exec*() 139<br />
exit() 143<br />
fork() 138<br />
open() 170, 172<br />
read() 172<br />
readdir() 172<br />
setuid() 420<br />
syslog() 464<br />
unlink() 172<br />
write() 126, 172<br />
Syscall-Interface 799<br />
sysctl 534<br />
sysfs 168<br />
sysinit 844<br />
Syslog 359<br />
syslog 587, 674<br />
syslog() 464<br />
syslog-ng 467<br />
syslogd 180, 464<br />
Konfiguration 468<br />
logcheck 472<br />
logrotate 471<br />
Remote-Logging 470<br />
SysRq 504<br />
Systat (Dienst) 589<br />
System Settings 716<br />
System V 50<br />
Systemarchitektur 113, 122<br />
Abstraktion 128<br />
Fairness 119<br />
Performance 127<br />
Schutz 119<br />
Virtualisierung 129<br />
systemsettings<br />
System Settings 716<br />
systrace 1118<br />
T<br />
tac 297, 298<br />
tail 293, 1234<br />
Tanenbaum, Andrew 53, 54<br />
tar 451, 487, 1235<br />
Task 132, 137<br />
Taskleiste 706<br />
Taskwechsel 161<br />
Tastaturbelegung 506<br />
Tcl 932<br />
TCP 585, 1102<br />
Verbindungen 539<br />
tcp (Schlüsselwort) 585<br />
TCP/IP 51, 513, 1251<br />
Schichtenmodell 514<br />
TCP 516<br />
tcp6 585<br />
tcpd 586<br />
tcpdump 542, 1162<br />
tcsh 211, 361<br />
tee 239<br />
telinit 846<br />
telnet 557, 585, 613, 671<br />
Telnet (Dienst) 590<br />
Temporäre Datei 357<br />
TENEX-C-Shell 211<br />
TERM 856<br />
Terminal 855<br />
test 343<br />
Text-to-Speech 766<br />
Thompson, Ken 49, 50<br />
Thrashing 157<br />
Thread 132, 136<br />
Kontrollblock 148<br />
Thunar 722<br />
tiemu 911<br />
tiff 985<br />
Time (Dienst) 589<br />
TIMTOWTDI 1055<br />
Tk 932, 983<br />
TLB 153<br />
Token 967<br />
top 804<br />
tor 1102<br />
Torvalds, Linus 53, 55, 61<br />
totem 765<br />
touch 1237<br />
tr 297, 298, 1238<br />
Tracing (Programme) 944<br />
Translation Lookaside Buffer 153<br />
Transparenter Proxy 1090<br />
Transport Layer 515<br />
Transports (Exim) 622<br />
1278
Index<br />
Treiber 162, 498, 759<br />
blockorientiert 165<br />
Major-Nummer 166<br />
Minor-Nummer 166<br />
zeichenorientiert 164<br />
Tremulous 788<br />
Trennungsoperator 218<br />
true 1238<br />
truss 945<br />
TrustedBSD 1118<br />
ts10 912<br />
tune2fs 894, 1196<br />
Tux 61<br />
TuxRacer 787<br />
TV-Karte 772<br />
twm 724<br />
type 219<br />
typescript 310<br />
typeset 337<br />
Typisierung (Perl) 1050<br />
U<br />
UAE 909, 910<br />
Ubuntu 57<br />
udev 875<br />
UDP 585, 1102<br />
udp6 585<br />
UFS 869<br />
UFS2 869<br />
UFS2-Attribute 1118<br />
UID 147, 377, 380<br />
umask 422<br />
UML 745<br />
UML (User-Mode-Linux) 900<br />
unalias 222<br />
uname 199, 222, 498, 1238<br />
uncompress 1213<br />
Unendlichkeit (L A T E X) 737<br />
ungif (Library) 985<br />
uniq 298, 1239<br />
Unity 720<br />
Unix 49<br />
BSD 50<br />
Geschichte 49<br />
Logging 1111<br />
Partitionierung 1112<br />
Philosophie 175<br />
Sicherheit 1067<br />
trojanisches Pferd 1110<br />
Unix Domain Sockets 824<br />
Unix System III 50<br />
Unix-Zeit 509<br />
unix2dos 510<br />
unix2mac 510<br />
unless 1055<br />
unlink() 172<br />
unrar 491<br />
unset 226, 341<br />
unsigned 996<br />
until 348, 1055<br />
update-grub 831, 832<br />
upgradepkg 444<br />
Upstart 852<br />
Job-Skript 852<br />
uptime 199, 1240<br />
URI 559<br />
usb-ohci 773<br />
USB-Platte 896<br />
USB-Stick 896<br />
usbcore 773<br />
usbfs 896<br />
Usenet 573<br />
User-Mode-Linux 900<br />
useradd 382<br />
userdel 390<br />
usermod 388<br />
Userspace 175, 1251<br />
USV 844<br />
utmp 846<br />
uucpd 585<br />
UUID 191<br />
V<br />
Variablen 225, 228<br />
Einbettung 226<br />
global 228<br />
löschen 226<br />
lokal 228<br />
schreibgeschützt 228<br />
Wert einlesen 227<br />
Variablentyp (Perl) 1049<br />
VAX 50<br />
Vega Strike 786<br />
Vektor (L A TEX) 738<br />
Verdeckter Kanal 1101<br />
Vergleichssymbol (L A T E X) 736<br />
Versionsmanagement 973<br />
Versteckte Dateien 196<br />
1279
Index<br />
Verzeichnis 878<br />
Verzeichnisdienst 400, 403<br />
vfat 896<br />
VFS 172, 180, 865, 1251<br />
vi 316, 1240<br />
<strong>aus</strong>schneiden 319<br />
autoindent 321<br />
Eingabemodus 317<br />
ersetzen 319<br />
Kommandomodus 317<br />
Konfiguration 321<br />
Navigation 318<br />
number 322<br />
shiften 320<br />
shiftwidth 322<br />
showmatch 322<br />
showmode 322<br />
speichern 317<br />
Statuszeile 316<br />
Suchfunktion 321<br />
tabstop 322<br />
Text kopieren 320<br />
vice 912<br />
Video-Decoder 767<br />
videodev 773<br />
vim 322<br />
Virenscanner 617<br />
Virtual Desktop 706<br />
VirtualBox 922<br />
VirtualHost 1189<br />
Virtualisierung 129, 899<br />
Virtuelle Adresse 520<br />
Virtuelle Maschine 899<br />
Virtuelle Schnittstelle 521<br />
Virtueller Speicher 119, 130<br />
Visio 745<br />
VLC 770<br />
VM 899<br />
VMware 922<br />
voice of God 760<br />
VoIP 1102<br />
Vokabeltrainer 753<br />
Volkerding, Patrick 56<br />
Vordergrundprozess 795<br />
vt220 856<br />
W<br />
w 463, 1240<br />
Wörterbuch 751<br />
WˆX 1117<br />
wait 585, 799, 843<br />
Warmux 786<br />
wc 299, 1241<br />
wd0 192<br />
Webcams 773<br />
Webserver 558<br />
WendzelNNTPd 594<br />
Authentifizierung 597<br />
starten 596<br />
wendzelnntpd.conf 595<br />
wendzelnntpdadm 596<br />
wget 565<br />
whatis 202, 1241<br />
whence 220<br />
which 220<br />
while 346, 1016, 1054<br />
while (C-Shell) 369<br />
while-true 347<br />
Whitelist 618<br />
who 463, 1241<br />
whoami 463, 1242<br />
whois 667<br />
wikipediafs 868<br />
Window Maker 723<br />
Window-Manager 704, 713<br />
Windows 68<br />
Freigaben 605<br />
Wine 902, 904<br />
Wireless LAN 522<br />
Wireshark 1164<br />
wish 933<br />
WKS 588<br />
WLAN 522, 1251<br />
konfigurieren 523<br />
Scanning 522<br />
Working Set 157<br />
Workspace 706<br />
write() 172<br />
writeback 867<br />
wsconsctl 507, 508<br />
wtmp 846, 859<br />
Wurzelzeichen (L A T E X) 737<br />
WYSIWYG 729<br />
X<br />
X-Sessions 709<br />
X.Org 688<br />
X10R4 687<br />
1280
Index<br />
X11 178, 563, 687, 1251<br />
ATI 702<br />
Client 688<br />
Geschichte 687<br />
Konfiguration 694<br />
M<strong>aus</strong>rad 698<br />
NVIDIA 702<br />
Programme 729<br />
Protokoll 688<br />
Server 688<br />
Terminal 691<br />
Toolkit 689<br />
vmware 700<br />
Window-Manager 704<br />
Zugriffskontrolle 690<br />
X11R1 688<br />
X11R5 688<br />
X11R6 688<br />
XArchiver 723<br />
xargs 246<br />
xauth 691<br />
XawTV 774<br />
XBoard 785<br />
xcalc 694<br />
XChat 573, 748<br />
xclock 694<br />
xconsole 694<br />
XDM 843<br />
xdm 706<br />
xdvi 732<br />
xedit 694<br />
xemacs 323<br />
Xen 913, 922<br />
Dom0 914<br />
DomU 914<br />
Hypervisor 913<br />
xm 917<br />
Xfburn 722<br />
XFCE 721<br />
Thunar 722<br />
XFree86 688<br />
XFS 867<br />
xhost 690, 710<br />
xhosts 691<br />
xine 770<br />
Xinerama 707<br />
xinetd 583, 587, 1069<br />
defaults 587<br />
instances 587<br />
Tageszeit 587<br />
UNLIMITED 587<br />
xinetd.conf 587<br />
xinetd.log 587<br />
xkill 694<br />
Xlib 689<br />
xload 694<br />
xm 917<br />
xmag 694<br />
xman 694<br />
Xnest 709<br />
XOR 1007<br />
xorg.conf 695<br />
Device 699<br />
Files 697<br />
InputDevice 697<br />
M<strong>aus</strong>rad 698<br />
Module 696<br />
Monitor 699<br />
Screen 700<br />
ServerFlags 697<br />
ServerLayout 701<br />
vmware 700<br />
Xpdf 746<br />
xpdf 732<br />
Xsecurity 691<br />
Xterm 692<br />
xterm 694<br />
xterm-color 856<br />
xtrs 913<br />
xv 747<br />
xwininfo 694<br />
Xxgdb 936<br />
Y<br />
yacc 964<br />
yes 1242<br />
yield() 160<br />
Yo Frankie 788<br />
Yorick 934<br />
ypbind 402, 403<br />
ypcat 401<br />
ypserv 403<br />
ypwhich 403<br />
Z<br />
Z-Shell 212<br />
Zahlen vergleichen 343<br />
zcat 491, 1213<br />
1281
Index<br />
Zeichenketten 1039<br />
Zeiger 1032<br />
Zertifikat 1098<br />
Zertifizierungsstelle 1098<br />
zfs 867<br />
zftp 212<br />
zlib 986<br />
Zombie-Prozess 1251<br />
Zone 900<br />
zsh 212<br />
zsnes 913<br />
Zugangsschutzsystem 1075<br />
zxpdf 746<br />
1282