17.11.2013 Aufrufe

6 Grundlagen aus Anwendersicht

6 Grundlagen aus Anwendersicht

6 Grundlagen aus Anwendersicht

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!