UNIX Shell-Programmierung

Ähnliche Dokumente
RFID für die Optimierung von Geschäftsprozessen

Der Standard-Editor vi

X Anmelden am System. X System herunterfahren. X Grundlegendes zur Shell. X Das Hilfesystem. X Dateioperationen. X Bewegen im Verzeichnisbaum

UNIX/Linux Lösung. Mär 14, 17 20:40 Seite 1/6. Prozeßsynchronisation (was ist das?, wo kommt es vor?, Beispiel?):

Ein- und Ausgabeumlenkung

Crashkurs Kommandozeile

Shell-Scripting Linux-Kurs der Unix-AG

Grundlagen der Programmierung

Shell-Scripting Linux-Kurs der Unix-AG

D.2 Sonderzeichen (2)

Unix Grundlagen. - ii - Ambit Professional Seminar Series. Autor: Prof. J. Anton Illik Diplom-Informatiker

Kommandozeilenverarbeitung durch die Unix-Shell (bash)

Shell-Scripting Linux-Kurs der Unix-AG

Übersicht Shell-Scripten

Systemprogrammierung I - Aufgaben zur Erlangung der Klausurzulassung für Informatiker und Wirtschaftsinformatiker

Arzu Sanli Ibrahim Canakci

Okt 10, 16 17:29 UNIX/Linux Lösung

Basiskonzepte des Rechnerbetriebs

Bash-Skripting Linux-Kurs der Unix-AG

Arbeiten mit der Shell Teil 2

Übungen zu Systemprogrammierung I Jürgen Kleinöder Universität Erlangen-Nürnberg Informatik 4, 2003 C-Uebung1.fm

Vorsemesterkurs Informatik

Bash-Scripting Linux-Kurs der Unix-AG

Linux Prinzipien und Programmierung

Shell-Programmierung für Unix und Linux

Filme der Kindheit Kindheit im Film

Linux Kommandozeile: Einfache Skripte. 1 Wiederhohlung. 2 Einfache Skripte

Aufgabensammlung IT Shellprogrammierung Teil I

Unix/Linux Grundlagen für Einsteiger

Shell-Programmierung

E-/A-Funktionalität nicht Teil der Programmiersprache

L A TEX, Linux, Python

Basiskonzepte des Rechnerbetriebs

Linux-Einführung Übung

Kapitel 2. Auf Tuchfühlung mit UNIX/Linux. 2.1 Einführung

Linux I II III Res WN/TT NLTK XML Weka E Theorie Terminal Ein- und Ausgabe. Linux I. 1 Linux I. Theorie Terminal Ein- und Ausgabe. Ressourcen-Vorkurs

Arbeiten mit der Shell Teil 1

Arbeiten in der Unix-Kommandozeile

Funktionen in JavaScript

Grundlagen der Informatik Vorlesungsskript

Bash-Skripting Linux-Kurs der Unix-AG

Funktionen in JavaScript

Shell-Scripting Linux-Kurs der Unix-AG

UNIX Die wichtigsten Befehle

Arbeiten in der Unix-Kommandozeile

Basiskonzepte des Rechnerbetriebs. 6 Die Shell: Der UNIX-Kommandointerpreter

Linux und Shell-Programmierung Teil 5

Feuerwehr-, Flucht- und Rettungspläne

Linux II. Reguläre Ausdrücke Editoren Scripting. 2 Linux II. Linux I II III Res WN/TT NLTK XML Weka E Reguläre Ausdrücke Editoren Scripting

Arbeiten mit der Shell Teil 1

SelfLinux Dateien unter Linux

Teil 1: Einführung in die Shell. Was ist die Shell? Wichtige Kommandos (1) Einführung in die Shell. Grundlagen der Shell-Programmierung

Die Unternehmergesellschaft

Linux / Unix - Shells

Linux I II III Res/Pro WN/TT Reguläre Ausdrücke Editoren Scripting. Linux II. 2 Linux II. Reguläre Ausdrücke Editoren Scripting. Ressourcen-Vorkurs

pwd mkdir Zeigt das aktuelle Verzeichnis an Beispiel: pwd

Arbeiten mit der Shell Teil 1

Desktop ade: Me and my shell

Vorlesung Unix-Praktikum

SelfLinux Was ist eine Shell?

Arbeiten mit der Shell Teil 1

Arithmetik in der tcsh

UNIX Grundlagen. Sascha Frank SS August 2006 UNIX I. Sascha Frank. Einführung. Basic Befehle. Quellen

Okt 02, 17 12:28 UNIX/Linux Lösung

Shell. Oder Konsole suchen im Application Finder. Auch Terminal, Bash oder Kommandozeile genannt. Bash nimmt Befehle entgegen und führt diese aus

Deshalb ist hello + world = 0. Umgekehrt gilt das Gleiche, weshalb 8 plus 3 gleich 83 ist. Dies ist in Zeile 5 in Terminal 2 gezeigt. In der Regel sol

Medizinische Statistik mit R und Excel

SelfLinux Dateien unter Linux

Kommandozeile und Batch-Dateien. Molekulare Phylogenetik Praktikum

Übung 4: Schreiben eines Shell-Skripts

1 EINLEITUNG Übersicht zum Buch... 5

EINFÜHRUNG IN LINUX DR. MATTHIAS M. HÖLZL

Hochschule Für Angewandte Wissenschaften FH München Sommersemester Thomas Kolarz. Folie 1.

Einführung Unix Shell

Der Windows Explorer INITE 7e 2003 Joël François

Skripte. Beispiel. M. Fyta Computergrundlagen 73/93

Das Handbuch zu KCron

JavaScript objektorientiert

Wissenschaftliche Arbeiten typografisch gestalten

Linux I II III Res/Pro WN/TT Theorie Terminal Ein- und Ausgabe. Linux I. 1 Linux I. Theorie Terminal Ein- und Ausgabe. Ressourcen-Vorkurs

Variablen in MATLAB. Unterschiede zur Mathematik: Symbolisches und numerisches Rechnen. Skriptdateien. for-schleifen.

Kurze Einweisung in die Shell

2 Konventionen und Begriffe zu diesem Buch

Linux und Shell-Programmierung Teil 6

Subprozesse in Python

Computer & GNU/Linux Einführung Teil 3

Übung: Entwickeln eines Shell-Skripts

Adobe Photoshop Lightroom 5 für Einsteiger

Übersicht PERL. !!!! Wichtig: Nach dem Befehl einem Strichpunkt setzen!!!!

Benutzung der Manpage, Shell Teil 3

Shell-Programmierung fur Unix und Linux

Technische Praxis der Computersysteme I 3. Vorlesung

Unterschiede in Dateien mit diff

Vorlesung Unix-Praktikum

Unix-Shells. mehrere Befehle in einer Zeile. bash: Grundlagen. Ein- und Ausgaben umlenken. Befehle: Dateien und Verzeichnisse (1)

mitp/die kleinen Schwarzen XING Erfolgreich netzwerken im Beruf Bearbeitet von Frank Bärmann

Stapelverarbeitungsdateien

Berechnungen in Excel

Kommandozeilen effizient nutzen und verstehen

Transkript:

UNIX Shell-Programmierung Bearbeitet von Rainer Krienke 2. Auflage 2001. Taschenbuch. XII, 275 S. Paperback ISBN 978 3 446 21722 5 Format (B x L): 14 x 21,1 cm Gewicht: 401 g Zu Inhaltsverzeichnis schnell und portofrei erhältlich bei Die Online-Fachbuchhandlung beck-shop.de ist spezialisiert auf Fachbücher, insbesondere Recht, Steuern und Wirtschaft. Im Sortiment finden Sie alle Medien (Bücher, Zeitschriften, CDs, ebooks, etc.) aller Verlage. Ergänzt wird das Programm durch Services wie Neuerscheinungsdienst oder Zusammenstellungen von Büchern zu Sonderpreisen. Der Shop führt mehr als 8 Millionen Produkte.

KAPITEL 2 2.DIE SHELL ALS KOMMANDOINTERPRETER In diesem Kapitel wird der Leser in die Möglichkeiten der Shell-Bedienung eingeführt. Im Anschluß an die Darstellung der Grundlagen, die für alle Varianten der Shell gleichermaßen gelten, werden die Besonderheiten der einzelnen Shell-Varianten beschrieben, so daß der Benutzer in die Lage versetzt wird, die von den Shells gebotenen Möglichkeiten sinnvoll einzusetzen. 2.1 GRUNDLAGEN In diesem Abschnitt werden Grundlagen dargestellt, die für das Verständnis der Arbeitsweisen aller Shell-Varianten wichtig sind. Überwiegend gilt dies für alle Shells in gleichem Maße. In den Fällen, in denen Unterschiede bestehen, werden diese gesondert dargestellt. 2.1.1 KOMMANDOS Eine der wichtigsten Aufgaben der Shell ist das Ausführen von Kommandos des Benutzers. Die Shell bildet somit die Schnittstelle zwischen dem Benutzer und Unix. Befehle, die ausgeführt werden sollen, können in der Kommandozeile der Shell eingegeben, editiert und schließlich nach dem Drücken der Return-Taste ausgeführt werden. Anschließend wertet die Shell die Kommandozeile aus (siehe Kapitel 2.1.6 auf Seite 17), startet das Kommando und gibt Ergebnisse oder Fehlermeldungen an den Benutzer aus. Als Zeichen der Eingabebereitschaft stellt die Shell vor jeder Kommandozeile den sogenannten Shell-Prompt dar, der aus einer vom Benutzer frei bestimmbaren Zeichenkette wie z.b. mr@hamlet> besteht, und oft auch den Pfad zu dem aktuellen Verzeichnis des Benutzers enthält. Jedes Kommando liefert nach seiner Ausführung einen Rückgabestatus, der aussagt, ob die Ausführung erfolgreich war oder ob ein Fehler aufgetreten ist. Ein Rückgabewert von 0 steht für eine erfolgreiche Ausführung. Ein anderer Wert steht für einen Fehler, wobei die Zahl bei vielen Kommandos die Fehlerart dokumentiert. Über das Kommando echo 7

2 DIE SHELL ALS KOMMANDOINTERPRETER $? kann der Rückgabestatus eines Kommandos direkt nach dessen Ausführung bestimmt werden. $? ist der Wert einer Shell-Variablen (siehe auch Kapitel 4 Seite 16), die immer den Rückgabewert des zuletzt ausgeführten Kommandos enthält. Folgendes Beispiel soll diesen Sachverhalt veranschaulichen: mr@hamlet> ls Mail adressen.txt etc tmp mr@hamlet> echo $? 0 mr@hamlet> ls /abcde /bin/ls: /abcde: No such file or directory mr@hamlet> echo $? 1 Im Anschluß an die Ausführung des ersten ls-kommandos ist der Rückgabewert 0, da bei der Ausführung von ls kein Fehler aufgetreten ist. Im zweiten Fall wurde durch das Kommando ls /abcde ein Fehler provoziert, da es das Verzeichnis /abcde nicht gibt. Der anschließend ermittelte Rückgabewert ist jetzt 1, wodurch ein Fehlerzustand signalisiert wird. Entschließt sich der Benutzer, ein Kommando, das er gerade eingibt oder ein Kommando, das er bereits durch Drücken von Return gestartet hat, abzubrechen, genügt es, die Tastenkombination Ctrl-c 1 zu drücken. 2.1.2 METAZEICHEN DER SHELL, QUOTING Metazeichen sind Zeichen, die eine besondere Bedeutung für die Shell haben. Ein Beispiel eines Metazeichens ist der *. Tritt dieses Zeichen in der Kommandozeile auf, versucht die Shell, es vor Ausführung der Kommandozeile durch eine Liste von Dateinamen zu ersetzen (daher wird diese Art der Ersetzung von Metazeichen zu Dateinamen durch die Shell auch Dateinamenersetzung genannt). Auf diese Art und Weise ist es z.b. möglich, daß alle Dateien eines Verzeichnisses mit dem Kommando mr@hamlet> ls * Mail adressen.txt etc tmp ausgegeben werden. Normalerweise ist diese Ausgabe genau das was man erreichen will. Was aber, wenn man nicht alle Dateien des aktuellen Verzeichnisses auflisten möchte, sondern nur eine Datei, die den Namen * 1 Ctrl-c bedeutet, daß gleichzeitig die Tasten Control und c gedrückt werden sollen. Auf deutschen Tastaturen muß anstelle von Control die Taste Steuerung verwendet werden. Auf manchen Systemen kann anstelle der Tastenkombination einfach die Taste Del gedrückt werden. 8

GRUNDLAGEN trägt (auch wenn eine solche Namensgebung nicht empfehlenswert ist)? Der Versuch dies mit dem Kommando 2.1 mr@hamlet> ls * zu erreichen, muß scheitern, da in diesem Fall alle Dateien des aktuellen Verzeichnisses ausgegeben werden. Um das Ziel zu erreichen, muß dem Sonderzeichen seine Sonderbedeutung genommen werden. Diesen Vorgang nennt man Quoten. Eine Möglichkeit, ein Sonderzeichen zu quoten besteht darin, dem Zeichen einen Backslash (\) voranzustellen. Daher versucht folgendes Kommando eine Datei mit dem Namen * aufzulisten: mr@hamlet> ls \* /bin/ls: *: No such file or directory Das Ergebnis ist eine Fehlermeldung des Kommandos ls, die aussagt, daß es im aktuellen Verzeichnis keine Datei mit dem Namen * gibt. ls hat also wie beabsichtigt versucht eine Datei mit diesem Namen aufzulisten. Das Sonderzeichen * hat in diesem Fall also tatsächlich seine Sonderbedeutung verloren. Neben dem * gibt es eine Reihe weiterer Sonderzeichen, die in Tabelle 1 beschrieben sind. Tabelle 1: Metazeichen der Shell Zeichen Bedeutung * Wird zu einem oder mehreren beliebigen Zeichen (auch der leeren Zeichenkette) für Dateinamen, ausgenommen Dateien mit einem. am Beginn, expandiert. Die sogenannten versteckten Dateien und Verzeichnisse mit einem Punkt am Anfang werden daher von diesem Metazeichen nicht erfaßt.? Wird zu einem beliebigen Zeichen eines Dateinamens expandiert. [s] [!s] [c1-cn] Wird mit einem Zeichen aus der Zeichenkette s entsprechend den verfügbaren Dateinamen ersetzt (z.b. würde ls t[mu]p die Dateien tmp und tup auflisten, wenn diese existieren). Wird mit einem Zeichen aus Dateinamen ersetzt, das nicht in s enthalten ist. Wird durch genau ein Zeichen eines Dateinamens aus den Zeichen c1-cn ersetzt, wie z.b. [a-z] (ein Buchstabe von a bis z ). 9

2 DIE SHELL ALS KOMMANDOINTERPRETER Tabelle 1: Metazeichen der Shell Zeichen {s1,s2,...} Bedeutung Das Ergebnis besteht aus Zeichenketten, in denen die in Klammern angegebenen Zeichenketten enthalten sind. In der Anweisung ls ha{nd,lt} würde z.b. der Klammerausdruck zu ls hand halt ersetzt werden. Nicht in der Bourne- und Korn-Shell verfügbar. $ Dieses Zeichen beschreibt den Beginn einer Variablen, deren Wert an dieser Stelle eingesetzt werden soll (z.b. echo $HOME). `kommando` SPACE, TAB Wird durch die Ausgaben, die kommando erzeugt, ersetzt. kommando darf ein beliebiges Programm sein, das seine Ausgaben auf stdout (= Bildschirm, siehe Kapitel 2.1.3 auf Seite 11) schreibt. Dienen als Trennzeichen, SPACE ist das Leerzeichen, TAB das Tabulatorzeichen. Mehrere Trennzeichen hintereinander werden bei der Kommandointerpretation von der Shell zu einem Zeichen verkürzt. Um den Metazeichen ihre besondere Bedeutung zu nehmen, kann man verschiedenen Methoden anwenden. Zum einen kann ein einzelnes Sonderzeichen durch voranstellen eines Backslash ( \ ) wie beispielsweise in ls \* entwertet werden. Eine weitere Methode besteht darin, Sonderzeichen in einfache Anführungszeichen zu fassen wie z.b. ls '*'. Innerhalb der einfachen Anführungszeichen verändert die Shell die Kommandozeile nicht. Die darin enthaltenen Sonderzeichen haben hier also keine Sonderbedeutung mehr. Dabei besteht noch ein feiner, aber wichtiger Unterschied zwischen einfachen (' ') und doppelten Anführungszeichen (" "). Der Unterschied betrifft die Ersetzung von Shell-Variablen, die in Kapitel 2.1.5 auf Seite 15 behandelt werden. Innerhalb von einfachen Anführungszeichen werden Shell-Variablen nicht durch ihren Wert ersetzt, innerhalb von doppelten Anführungszeichen hingegen schon, wie folgendes Beispiel zeigt ($HOME enthält den Pfad zum Home-Verzeichnis des Benutzers): mr@hamlet(6)> ls "$HOME" Mail adressen.txt etc tmp mr@hamlet(7)> ls '$HOME' /bin/ls: $HOME: No such file or directory 10

GRUNDLAGEN In Tabelle 2 sind noch einmal alle Quoting-Möglichkeiten mit ihrer Bedeutung zusammengefaßt, um dem Leser einen schnelleren Überblick zu ermöglichen. 2.1 Tabelle 2: Quote-Zeichen Quotezeichen Bedeutung \ Das direkt rechts von diesem Zeichen stehende Sonderzeichen verliert seine Sonderstellung. ' ' Innerhalb dieser einfachen Anführungszeichen stehender Text wird von der Shell nicht verändert. Alle darin enthaltenen Sonderzeichen verlieren also ihre Sonderbedeutung. Variablen werden nicht durch ihren Wert ersetzt. " " Innerhalb dieser Anführungszeichen verlieren alle Sonderzeichen außer $ ihre Sonderbedeutung. Shell oder Environment-Variablen, die innerhalb dieser Zeichen vorkommen, werden daher durch ihren Wert ersetzt. `kommando` $(kommando) Diese Zeichen führen zum Start von kommando, dessen Ausgaben als Ergebnis geliefert werden. In diesen Anführungszeichen stehende Variablen werden vor der Ausführung durch ihren Wert ersetzt. Die Schreibweise $(kommando) kann mit der gleichen Bedeutung in der Bourne-Again- und Korn-Shell alternativ verwendet werden. Diese Art der Ersetzung wird auch Kommandoersetzung genannt. 2.1.3 KONZEPT DER EIN- UND AUSGABE Unix bietet dem Benutzer die Möglichkeit, die Ein- und Ausgaben eines Programms zu beeinflussen. Grundlage dieser Möglichkeiten ist das Ein- Ausgabekonzept von Unix: es existieren drei vordefinierte Datenkanäle, die die Bezeichnungen stdin(0), stdout(1) und stderr(2) tragen. Die in Klammern stehende Nummer ist die Zahl, die den Datenkanälen fest zugeordnet wurde. Deren Bedeutung wird weiter unten erklärt. Startet man ein Programm, das Eingaben vom Benutzer benötigt, liest dieses Programm vom Datenkanal stdin. Normalerweise ist stdin der Tastatur zugeordnet, so daß Eingaben für eine Applikation über die Tastatur vorgenommen werden können. Ausgaben kann das Programm entweder auf stdout oder auf stderr schreiben. stdout ist der Standardausgabe Kanal, der normalerweise dem Terminal zugeordnet ist, von dem aus das Programm gestartet wurde. Schreibt ein Programm Daten auf stdout, erscheinen diese also auf dem Bildschirm. Der dritte Datenkanal 11

2 DIE SHELL ALS KOMMANDOINTERPRETER stderr wird von Programmen i.d.r. dazu verwendet, Status- oder Fehlermeldungen auszugeben. Auch stderr ist normalerweise dem Terminal zugeordnet, von dem aus das Programm gestartet wurde. Der Vorteil der Unterscheidung von stdout und stderr wird dann ersichtlich, wenn man weiß, daß die Shell die Möglichkeit bietet, alle drei Datenkanäle umzulenken. Auf diesem Weg ist es beispielsweise möglich, die Ausgaben eines Programms in eine Datei umzuleiten, um sie später in Ruhe ansehen zu können. Fehlerausgaben erscheinen nach Wunsch weiterhin auf dem Bildschirm oder können in eine zweite Datei umgelenkt werden. Auch die Eingabe kann auf diese Weise umgeleitet werden. Daher kann ein Programm, das normalerweise seine Eingaben durch den Benutzer von der Tastatur aus erhalten würde, seine Eingabedaten ebenso von einer Datei lesen. Die Umlenkung der Datenkanäle erfolgt mit Hilfe der <, >-Symbole. Soll z.b. die Standardausgabe (stdout) umgelenkt werden, wird einfach hinter dem Kommando das >-Zeichen geschrieben, dem der Name der Datei folgt, auf die die Ausgaben geschrieben werden sollen. Möchte der Benutzer beispielsweise die Ausgaben des Kommandos ls auf die Datei ls.txt umlenken, muß der Aufruf wie folgt lauten: mr@hamlet> ls > ls.txt mr@hamlet> ls /abcd > ls.txt /bin/ls: /abcd: No such file or directory Wie man an dem Ergebnis der ersten Eingabe sieht, werden die Ausgaben des Kommandos ls nicht mehr auf den Bildschirm, sondern in die Datei ls.txt geschrieben. Die Datei wird von der Shell automatisch angelegt, falls sie noch nicht existiert, oder gelöscht, wenn sie schon existiert. Der zweite Versuch demonstriert, daß die Ausgabeumlenkung nur für die normalen Ausgaben Gültigkeit hat, nicht jedoch für die Fehlermeldungen, die in diesem Beispiel dadurch provoziert wurde, daß versucht wurde, ein nicht existierendes Verzeichnis /abcd aufzulisten. Obwohl die Ausgabe über das >-Zeichen umgelenkt wurde, erscheinen Fehlermeldungen nach wie vor auf dem Bildschirm, da der Fehlerdatenkanal stderr nicht umgeleitet wurde. Um dies zusätzlich zu erreichen muß eine Shell-spezifische Syntax verwendet werden, die in Tabelle 3 auf Seite 13 beschrieben ist. Zur Umlenkung der Eingabe eines Kommandos muß das <-Zeichen verwendet werden. Soll beispielsweise die Datei /etc/passwd nach der Zeichenkette root durchsucht werden, wobei die Ergebnisse in die Datei grep.result geschrieben werden sollen, sieht die dazu notwendige Kommandozeile wie folgt aus: mr@hamlet> grep root < /etc/passwd > grep.result 12

GRUNDLAGEN Möchte man die Ausgaben (stdout) eines Kommandos an eine bestehende Datei anhängen, ohne diese zu überschreiben, kann anstelle von > das Zeichen >> verwendet werden: 2.1 mr@hamlet> ls /etc >> ls.txt Die Möglichkeiten der Umlenkung von Ein- und Ausgabe in den verschiedenen Varianten der Shell ist in folgender Tabelle dargestellt. Die dort verwendeten Bezeichnungen file und file1 stehen für zwei beliebige Dateinamen. Tabelle 3: Ein-/Ausgabe Umlenkungsmöglichkeiten Umlenkung von... Bourne/Korn/Bourn- Again-Shell C/TC-Shell stdin < file < file stdout > file > file stderr 2> file Separate Umlenkung nicht möglich stdout und stderr getrennte Umlenkung von stdout und stderr auf verschiedenen Dateien >file 2>&1 (Reihenfolge beachten!) >file 2>file1 >& file Separate Umlenkung nicht möglich stdout (an bestehende Datei anhängen) >> file >> file stdout und stderr (an bestehende Datei anhängen) >>file 2>&1 >>& file Wie aus der der oben stehenden Tabelle sichtbar wird, ist in der C- und TC- Shell keine separate Umlenkung von stdout und stderr möglich. Mit Hilfe eines kleinen Tricks kann dies dennoch erwirkt werden. Angenommen stdout und stderr eines ls-aufrufs in der C-Shell sollen getrennt werden. Hierzu kann die folgende Kommandosequenz verwendet werden:... (ls > stdout.txt) >& stderr.txt... 13

2 DIE SHELL ALS KOMMANDOINTERPRETER Der Trick besteht darin, das Kommando in einer Subshell (siehe Seite 20) auszuführen, in der stdout umgelenkt wird und anschließend alle anderen Ausgaben (also stderr) über eine Ausgabeumlenkung für diese Subshell zu realisieren. 2.1.4 KONZEPT DER PIPES Ein weiteres wichtiges Konzept in Unix ist das der Pipes. Pipes gestatten es dem Benutzer, mehrere Kommandos miteinander zu verbinden, indem die Ausgaben eines Kommandos als Eingaben eines weiteren dienen können. Zu diesem Zweck muß lediglich das Pipe-Zeichen zwischen die beiden (oder mehreren) Kommandos eingefügt werden. Angenommen, man möchte alle Dateien eines Verzeichnisses auflisten und nur die Ausgaben sehen, deren Name die Zeichenkette tm enthalten, kann folgende Kommandozeile verwendet werden: mr@hamlet> ls -lr grep tm drwxrw-rw- 2 mr employee 2048 Nov 24 12:10 tmp... In diesem Beispiel wurden die Ausgaben des Kommandos ls durch die Verwendung des -Zeichens nicht auf dem Bildschirm ausgegeben, sondern direkt als Eingabe für das Kommando grep verwendet, das die gesuchten Zeilen ausgibt. ls stdout stdin grep stdout stderr stderr Abb. 3: Funktionsweise einer Pipe In Abb. 3 ist die prinzipielle Funktionsweise einer Pipe am Beispiel der Kommandofolge ls grep nochmals graphisch dargestellt. Man sieht, wie die Ausgaben des ersten Kommandos direkt als Eingaben für das nächste Kommando dienen. Dieser Mechanismus kann durchaus mehrstufig sein, so daß auch die Ausgaben des zweiten Kommandos wiederum als Eingaben für ein drittes dienen können usw. Darüber hinaus erkennt man, daß Fehlerausgaben, die über stderr gemacht werden, nicht vom Mechanismus der Pipe beeinflußt werden. 14

2.1.5 KONZEPT DER SHELL- UND ENVIRONMENT-VARIABLEN GRUNDLAGEN 2.1 Shell- und Environment-Variablen ermöglichen es dem Benutzer, sowohl das Verhalten der Shell zu konfigurieren als auch eine den eigenen Bedürfnissen entsprechende Arbeitsumgebung zu schaffen. Dies geschieht, indem der Benutzer den Variablen entsprechende Werte zuweist. Dabei muß zwischen den Shell-Variablen, die nur zur Steuerung des Verhaltens der Shell dienen, und den Environment-Variablen unterschieden werden, die dazu dienen, das Verhalten von Programmen zu beeinflussen, die aus der Shell heraus gestartet werden. Ein Beispiel für eine Shell-Variable ist PS1 (Bourne-, Korn- und Bourne-Again-Shell), die bestimmt, wie der Prompt aussehen soll, den der Benutzer als Eingabeaufforderung erhält. Durch die Veränderung des Werts dieser Variablen kann der Benutzer das Erscheinungsbild seiner Shell verändern. Neben der Verwendung von Shell-Variablen wie PS1, die eine genau festgelegte Bedeutung hat, kann der Benutzer auch eigene neue Variablen definieren, beispielsweise um sich einen oft benötigten und schwierig zu schreibenden Pfadnamen in einer solchen Variablen zu merken. Anstatt immer wieder diesen Pfad von Hand eingeben zu müssen, kann der Benutzer dann einfach auf die entsprechende Variable der Shell zugreifen und spart somit viel Schreibarbeit. Ein Beispiel für eine Environment-Variable ist HOME, sie enthält immer den Pfad zum Home-Verzeichnis des Benutzers. Da die Liste der Environment-Variablen einem Programm (z.b. cd) beim Start verfügbar gemacht wird, hat es die Möglichkeit, beispielsweise anhand der Variablen HOME, das Home-Verzeichnis des Benutzers festzustellen, um dort z.b. Programm-Konfigurationsdateien abzulegen oder lesen zu können. Das Kommando cd verwendet beispielsweise den Wert der Variablen HOME als Verzeichnis, in das gewechselt werden soll, wenn cd ohne Parameter aufgerufen wird. Der Zugriff auf den Wert einer Shell- und Environment-Variablen erfolgt stets durch das Voranstellen des $-Zeichens vor den Namen der Variablen. Um beispielsweise den Wert der Environment-Variablen HOME zu ermitteln, lautet das Kommando echo $HOME. Der Befehl echo dient zur Ausgabe von Text und/oder Variablen, $HOME ergibt den Wert der Variablen HOME, der an dieser Stelle ausgegeben wird. Wie bereits erwähnt, handelt es sich bei Shell- und Environment-Variablen um zwei Paar Schuhe: Jede Shell verwaltet getrennt voneinander eine Liste mit Shell-Variablen und eine zweite Liste mit Environment-Variablen. In Abb. 4 auf Seite 16 ist dieser Zusammenhang nochmals graphisch dargestellt. Man erkennt die unterschiedlichen Wirkungsweisen der beiden Variablenarten: Shell-Variablen steuern das Verhalten und Aussehen der Shell selbst, wie z.b. die Variable PS1 (für die Bourne/Bourne-Againund Korn-Shell) den Aufbau des Shell-Prompts beschreibt. Environment- Variablen hingegen, wie z.b. die Variable MANPATH, werden allen Program- 15

2 DIE SHELL ALS KOMMANDOINTERPRETER Shell Shell-Variablen UID=216 TERM=vt100 PS1=mr@hamlet> HISTSIZE=100 Möglichkeit, Variablen in das Environment zu exportieren Steuerung des Verhaltens und Aussehens der Shell Environment- Variablen HOME=/home/mr PATH=/bin:/usr/bin TERM=vt100 MANPATH=/usr/man Bei Start eines Kommandos Bereitstellen der Environment-Variablen an das Kommando (hier: insbesondere die Variable MANPATH für das Kommando man). mr@hamlet> man ls Abb. 4: Shell- und Environment-Variablen men, die aus dieser Shell heraus gestartet werden, zugänglich gemacht, die anschließend die Werte der für sie wichtigen Variablen lesen können. In Abb. 4 durchsucht beispielsweise das Kommando man nach dem Start die Liste der Environment-Variablen nach einer Variablen MANPATH, die eine Liste von Pfadangaben enthält, in denen das Kommando man nach Handbucheinträgen suchen soll. Eine weitere Eigenschaft von Environment-Variablen ist die Vererbbarkeit. Startet man eine neue Shell, erbt diese das gesamte Environment der Shell, aus der heraus sie gestartet wurde. Ebenfalls in Abb. 4 dargestellt ist die Möglichkeit der zur Bourne-Shell aufwärtskompatiblen Shell-Varianten, Shell-Variablen zu exportieren. Dadurch ist eine solche Variable mit ihrem Wert anschließend auch im Environment der Shell verfügbar. Der Befehl export macht also aus einer Shell-Variablen eine Environment-Variable. Die C/TC-Shell kennt diese Möglichkeit nicht. Hier muß beim Setzen einer Variablen entschieden werden, ob sie eine Shell- oder eine Environment-Variable sein soll (siehe Kapitel 2.3.2 auf Seite 51). 16

2.1.6 BEARBEITUNG DER KOMMANDOZEILE GRUNDLAGEN 2.1 Vor der eigentlichen Ausführung eines vom Benutzer eingegebenen Kommandos durch die Shell, wertet diese die gesamte Kommandozeile aus. Dabei werden beispielsweise Sonderzeichen wie der * durch Dateinamen oder in der Kommandozeile stehende Variablennamen durch ihre Werte ersetzt. Da man die Ergebnisse solcher Ersetzungen nicht direkt beobachten kann, scheinen die gestarteten Programme oftmals nicht das zu tun, was man beabsichtigt hatte. Um solche Probleme erkennen und lösen zu können, ist ein genaueres Verständnis der Vorgänge erforderlich, die bei der Bearbeitung der Kommandozeile durch die Shell unsichtbar ablaufen. Daher sollen die wesentlichen Schritte hier kurz beschrieben werden: 1. Die Shell liest bis zum ersten Kommandotrenner (& && ; < >) und stellt fest, ob Zuweisungen an Variablen erfolgen sollen oder die Ein- oder Ausgabe umgelenkt werden soll. 2. Die Shell zerlegt die Kommandozeile in einzelne Argumente. Sie trennt die Argumente durch Trennzeichen, normalerweise das Leerund Tabulator-Zeichen. 3. Variablen (mit vorangestelltem $), die in der Kommandozeile stehen, werden durch ihre Werte ersetzt. 4. Kommandos, die in Apostrophen (` `) stehen, werden ausgeführt und durch ihre Ausgabe ersetzt. 5. stdin, stdout und stderr werden gemäß den Angaben auf der Kommandozeile umgelenkt. 6. Falls in der Kommandozeile Zuweisungen an Variablen stehen, werden diese ausgeführt. 7. Die Shell sucht nach Sonderzeichen (*,?, [ ],...) und ersetzt diese, sofern sie nicht in quote-zeichen (" ", ' ', \) gefaßt sind, durch passende Dateinamen. 8. Die Shell führt das Kommando aus. Ein Beispiel soll diesen Ablauf verdeutlichen. Da es in diesem Fall wesentlich ist, welche Dateien im aktuellen Verzeichnis des Benutzers liegen, gelte die Annahme, daß sich lediglich die Verzeichnisse tmp und etc dort befinden. Weiterhin soll das Verzeichnis tmp die Dateien titel und text.bak enthalten. Das aktuelle Verzeichnis des Benutzers sei sein Home-Verzeichnis. Die Abfolge der einzelnen Aktionen, die die Shell auf 17

2 DIE SHELL ALS KOMMANDOINTERPRETER der unten stehenden Kommandozeile ausführt, werden entsprechend der oben dargestellten Numerierung dargestellt. Falls in einem der Schritte keine Aktion erfolgt, steht an dieser Stelle ein mr@hamlet> ls -l `pwd` $HOME/etc tmp/* > ls.txt 1. Die Shell liest bis zum >-Zeichen und bearbeitet zunächst den links davon stehenden Teil der Kommandozeile weiter. 2. Die Kommandozeile wird in die Argumente ls -l, `pwd`, $HOME/ etc und tmp/* zerlegt. 3. Die Variable $HOME wird durch ihren Wert, also das Home-Verzeichnis des Benutzers, das beispielsweise /home/mr lauten könnte, ersetzt. Die Kommandozeile lautet jetzt: ls -l `pwd` /home/mr/etc tmp/* 4. Das in ` ` stehende Kommando pwd wird ausgeführt. Die Ausgabe des Kommandos (/home/mr) wird anstelle von `pwd` in die Kommandozeile eingefügt, so daß die Kommandozeile jetzt wie folgt aussieht: ls -l /home/mr /home/mr/etc tmp/* 5. stdout wird auf die Datei ls.txt umgelenkt. Falls diese Datei noch nicht existiert hat, wird sie angelegt, ansonsten wird der bisherige Inhalt gelöscht. 6. 7. Das Sonderzeichen * in dem Argument tmp/* wird, da der Stern nicht durch Quote-Zeichen geschützt ist, durch Dateinamen der im Verzeichnis tmp liegenden Dateien ersetzt (da * für beliebige und beliebig viele Zeichen von Dateinamen steht). Die Kommandozeile lautet schließlich: ls -l /home/mr /home/mr/etc tmp/titel tmp/text.bak 8. Das Kommando wird ausgeführt. 2.1.7 GRUPPIEREN VON KOMMANDOS Normalerweise gibt der Benutzer ein Kommando ein, beendet die Eingabe durch Drücken der Return-Taste und wartet, bis das Kommando ausge- 18

GRUNDLAGEN führt wurde und die Shell wieder den Prompt anzeigt, um ihre Eingabebereitschaft zu signalisieren. Unter Umständen ist es jedoch sinnvoll, mehrere Kommandos in einem Zug auszuführen, Kommandos gleichzeitig abarbeiten zu lassen oder ein Kommando in Abhängigkeit vom Erfolg oder Mißerfolg eines vorangegangenen Befehls auszuführen. Zu diesem Zweck wird der Rückgabewert, den jedes Kommando liefert, ausgewertet. Ein Rückgabewert von 0 bedeutet, daß ein Kommando erfolgreich ausgeführt werden konnte, ein anderer Wert bedeutet einen Fehler. Der Rückgabewert eines Kommandos kann direkt nach dessen Ausführung über die Shell-Variable? mit dem Kommando echo $? ausgegeben werden. Zur Gruppierung von Kommandos bietet die Shell verschiedene Möglichkeiten, die in folgender Tabelle aufgelistet sind: 2.1 Tabelle 4: Symbole zur Gruppierung von Kommandos Symbol Bedeutung ; Bewirkt, daß die einzelnen Kommandos, die durch dieses Zeichen getrennt sind, nacheinander ausgeführt werden. Der Rückgabewert ($?) des gesamten Kommandos entspricht dem des zuletzt ausgeführten. & k1 && k2 k1 k2 Das Anhängen dieses Zeichens an ein Kommando bewirkt, daß die Anweisung im Hintergrund ausgeführt wird; D.h. die Shell meldet sich sofort wieder mit dem Shell-Prompt eingabebereit, so daß weitere Kommandos gestartet werden können, noch während das mit & gestartete Kommando weiter ausgeführt wird. Diese Anweisung fragt den Status des Kommandos k1 ab und arbeitet in Abhängigkeit des Ergebnisses das nächste Kommando k2 ab oder überspringt es. Das nächste Kommando k2 wird nur dann bearbeitet, wenn das vorhergehende einen Rückgabewert von 0 (OK) hatte. Der Rückgabewert ($?) des gesamten Kommandos entspricht dem des zuletzt ausgeführten. Wie && fragt auch diese Anweisung den Rückgabewert des Kommandos k1 ab. Das nächste Kommando k2 wird jedoch nur dann bearbeitet, wenn das vorangegangene einen Rückgabewert ungleich 0 (Fehler) hatte. Der Rückgabewert ($?) des gesamten Kommandos entspricht dem des zuletzt ausgeführten. 19

2 DIE SHELL ALS KOMMANDOINTERPRETER Tabelle 4: Symbole zur Gruppierung von Kommandos Symbol (kommando) Bedeutung Das Kommando wird in einer Sub-Shell ausgeführt. Eine neue Shell wird gestartet, in der die Ausführung des Kommandos erfolgt. Anschließend wird diese Shell wieder beendet. Dadurch, daß eine neue Shell gestartet wird, wirken sich Veränderungen auf Shell- und Environment-Variablen durch kommando nur auf die neu gestartete Shell und nicht auf die Shell aus, in der die Anweisung (kommando)eingegeben wurde! Die Wirkungsweise der Gruppierungsanweisungen läßt sich am besten anhand einiger Beispiele beschreiben: mr@hamlet> ls; cd..; ls; cd In diesem Beispiel werden die Kommandos von links nach rechts nacheinander ausgeführt. Das jeweils folgende Kommando kann erst ausgeführt werden, wenn das vorangegangene beendet ist. mr@hamlet> sleep 100& mt@hamlet()> ls In diesem Beispiel wird an das Kommando sleep, das nichts anderes macht als die in Sekunden angegebene Zeit zu warten, ein & angehängt. Dadurch erscheint sofort wieder der Shell-Prompt und ein weiteres Kommando (hier ls) kann eingegeben werden. Beide Kommandos laufen jetzt parallel. mr@hamlet> ls && echo "Hat geklappt!" Mail etc tmp Hat geklappt! In diesem Beispiel erscheinen als Ausgabe zunächst die Dateien im aktuellen Verzeichnis des Benutzers. Da das Kommando ls, im eigenen Home-Verzeichnis aufgerufen, erfolgreich ablaufen kann, ist der Rückgabestatus 0. Daher wird anschließend das Kommando echo ausgeführt. mr@hamlet> ls /abcde && echo "Hat geklappt!" /abcde: No such file or directory Dadurch, daß bei der Ausführung von ls hier ein Fehler provoziert wurde, indem ein nicht existierendes Verzeichnis aufgelistet werden sollte, ist der Rückgabestatus von ls ungleich 0. Daher wird das hinter && stehende Kommando nicht ausgeführt. Als Ausgabe erscheint daher lediglich die Fehlermeldung von ls. 20

2.1.8 ARBEITEN MIT SUB-SHELLS GRUNDLAGEN 2.1 Sub-Shells sind immer dann von Nutzen, wenn man einige Kommandos in einer anderen Umgebung (in einem anderen Arbeitsverzeichnis oder mit anderen Werten für Shell- oder Environment-Variablen) ablaufen lassen möchte, ohne dabei die Umgebung der Shell, aus der heraus das Kommando aufgerufen wird, zu verändern. Eine Sub-Shell wird dadurch gestartet, daß man in der Kommandozeile runde Klammern verwendet: mr@hamlet> pwd; (cd /tmp; pwd); pwd /home/mr /tmp /home/mr In diesem Beispiel werden die Kommandos cd /tmp; pwd in einer Sub- Shell ausgeführt. Die öffnende runde Klammer bewirkt, daß eine neue Shell gestartet wird, bevor die rechts davon stehenden Kommandos gestartet werden. An der schließenden Klammer wird die Shell wieder beendet. Betrachtet man sich die Ausgaben des Beispiels einmal genauer, sieht man die Auswirkung der Sub-Shell. Die erste Ausgabe des Kommandos pwd liefert das aktuelle Verzeichnis des Benutzers /home/mr. Nach Ausführung des Kommandos cd /tmp in der Sub-Shell ist das Arbeitsverzeichnis dieser Sub-Shell jetzt /tmp, wie der zweite Aufruf des Kommandos pwd bestätigt. Obwohl jetzt kein cd-kommando mehr ausgeführt wird, liefert das dritte pwd-kommando wieder den Pfad /home/mr. Der Grund dafür liegt darin, daß die Kommandos, die in der Sub-Shell ausgeführt werden, zwar das Arbeitsverzeichnis dieser neu gestarteten Shell verändern, jedoch nicht das Arbeitsverzeichnis der Shell beeinflussen können, in der das erste und das letzte pwd-kommando aufgerufen werden. Obige Kommandozeile ist vergleichbar mit folgenden Anweisungen (Text der in einer Zeile hinter dem #-Zeichen steht, betrachtet die Shell als Kommentar. Diese Zeichenketten müssen also nicht mit eingegeben werden): mr@hamlet> pwd /home/mr mr@hamlet> sh # Entspricht: ( mr@hamlet> cd /tmp; pwd # Kommandos in der Sub-Shell /tmp mr@hamlet> exit # Entspricht: ) mr@hamlet> pwd /home/mr 2.1.9 KONTROLLE VON PROZESSEN (JOBCONTROL) Die in diesem Buch besprochenen Shell-Varianten, mit Ausnahme einiger Varianten der Bourne-Shell, unterstützen die sogenannte Jobcontrol. Dar- 21

2 DIE SHELL ALS KOMMANDOINTERPRETER unter versteht man die Möglichkeit, gestartete Programme in ihrer Ausführung steuern zu können. So besteht die Möglichkeit, ein Kommando, das gerade gestartet wurde, zu unterbrechen, so daß das Programm in einen Wartezustand versetzt wird. Das Programm ist nicht beendet, aber es arbeitet auch nicht. Mit bestimmten Kommandos kann man das Programm anschließend wieder aktivieren, und zwar wahlweise im Vordergrund (neuer Shell-Prompt kommt erst, wenn das Programm beendet ist) oder im Hintergrund (es erscheint direkt ein neuer Shell-Prompt und das Programm arbeitet weiter). Beispielsweise kann man ein gerade im Vordergrund laufendes Programm durch gleichzeitiges Drücken der Taste Control (oder Strg, bei deutschen Tastaturen) und Z (kurz Ctrl-z) unterbrechen. Anschließend besteht die Möglichkeit, dieses Programm mit dem Kommando fg wieder im Vordergrund weiterarbeiten zu lassen, oder es mit dem Kommando bg in den Hintergrund zu verlagern: mr@hamlet(24)> sleep 1000 # Programm laeuft im Vordergrund Ctrl-z # Unterbrechung mr@hamlet(25)> bg # Verlagen in den Hintergrund [1] 345 # Jobnummer fuer dieses Programm Die Jobnummer dient dazu, sich auf ein bestimmtes Programm, das im Hintergrund abläuft, beziehen zu können. Sie besteht aus einer in eckigen Klammern stehenden Zahl und einer weiteren, rechts davon stehenden Zahl wie etwa: [1] 345. Die Zahl in Klammern wird immer um eins erhöht, wenn ein weiteres Programm im Hintergrund arbeitet. Die rechts davon stehende Zahl ist die Prozeßnummer des Programms. Soll beispielsweise der eben gestartete sleep-prozeß wieder in den Vordergrund geholt werden, genügt das Kommando: mr@hamlet> fg %1 Die Schreibweise %1 meint, daß das Kommando (hier fg) auf das Programm mit der Jobnummer 1 angewendet werden soll, also auf den noch im Hintergrund arbeitenden sleep-prozeß. Alternativ kann ein Programm auch mit Hilfe des Kommandos kill und der Angabe der Jobnummer abgebrochen werden. Folgendes Kommando bricht einen im Hintergrund ablaufenden Prozeß mit der Jobnummer 1 ab: mr@hamlet> kill %1 Da es oftmals vorkommt, daß mehrere Programme in den Hintergrund gelegt wurden, ist es nützlich herauszufinden, um welche Programme es sich handelt und welche Jobnummer ihnen zugewiesen wurde. Diesem 22

DIE BOURNE-, BOURNE-AGAIN- UND KORN-SHELL Zweck dient das Kommando jobs. Gibt man dieses Kommando ein, werden alle zur Zeit im Hintergrund ablaufenden Programme zusammen mit ihrer Jobnummer aufgelistet. 2.2 2.2 DIE BOURNE-, BOURNE-AGAIN- UND KORN-SHELL Sowohl die Bourne-Again-Shell (Programmname: bash) als auch die Korn- Shell (ksh) basieren auf und sind aufwärtskompatibel zur Bourne-Shell (sh). Daher sollen an dieser Stelle alle drei Varianten beschrieben werden. Begonnen wird mit der Beschreibung der Bourne-Shell selbst. An Stellen, an denen die Korn- und Bourne-Again-Shell Erweiterungen gegenüber der Bourne-Shell bieten, werden diese beschrieben und entsprechend kenntlich gemacht, so daß der Benutzer erkennen kann, welche Erweiterungen für welche Shell gültig sind. 2.2.1 UNTERSTÜTZUNG DER KOMMANDOEINGABE Eine der wichtigsten Aufgaben der Shell ist die Interaktion mit dem Benutzer, der ständig Eingaben vornimmt, die von der Shell interpretiert und ausgeführt werden müssen. Um den Benutzer bei der Eingabe von Kommandos zu unterstützen, bieten sowohl die Korn- als auch die Bourne-Again-Shell Möglichkeiten an, die dem Benutzer eine komfortable Kommandoeingabe ermöglichen. Zu diesen Möglichkeiten zählt beispielsweise das Wiederholen bereits eingegebener Kommandos oder etwa die Vervollständigung von teilweise eingegebenen Datei- oder Verzeichnisnamen. Lediglich die Bourne-Shell bietet dem Benutzer in dieser Hinsicht keinerlei Unterstützung. Daher wird sie auch kaum noch zur Interaktion mit dem Benutzer, also als Login-Shell, verwendet. Sie hat jedoch immer noch ihren festen Platz bei der Ausführung von Shell-Skripten, da die Bourne- Shell weniger Ressourcen des Rechners zur Ausführung eines Shell-Programms benötigt als viele der Konkurrenten, wie etwa die Korn-Shell. Daraus folgt, daß die in diesem Abschnitt beschriebenen Unterstützungen der Kommandoeingabe lediglich für die Korn-Shell und die Bourne- Again-Shell gültig sind, aber nicht für die Bourne-Shell. Abkürzung eines Loginverzeichnisses mit ~ Bei der Eingabe von Kommandos kommt es häufig vor, daß man sich auf das eigene Home-Verzeichnis beziehen muß, beispielsweise wenn der Benutzer eine Datei in sein Home-Verzeichnis kopieren möchte. Anstatt den Pfad von der Wurzel des Dateibaums aus bis zu seinem Home-Verzeichnis (z.b. /home/mr) immer wieder eingeben zu müssen, gestatten es die Korn- und die Bourne-Again-Shell, den Pfad zum Home-Verzeichnis 23