340 likes | 484 Views
Shell. Einführung in die Bourne – Shell Vortrag: Martin Hiersche 23./30. 5. 2000. Was ist die Shell ?.
E N D
Shell Einführung in die Bourne – Shell Vortrag: Martin Hiersche 23./30. 5. 2000
Was ist die Shell ? • Während einer Sitzung am Rechner kommuniziert der Benutzer normalerweise nicht mit dem Betriebssystem sondern mit einem Programm welches seine Kommandos liest, analysiert und dann entweder selbst ausführt oder an andere Programme weiterreicht. Dieses Programm wird deshalb als Kommandointerpreter bezeichnet und trägt den Namen Shell (der Name der Programmdatei ist /bin/sh), weil sie wie eine Schale um den Kern des Systems liegt. • Auf den unterschiedlichen UNIX - Implementierungen existieren eine Reihe verschiedener Shell - Programme. Die Shell des Standard - UNIX - Systems wird nach ihrem Autor auch als BOURNE - SHELL bezeichnet. Eine zweite, sehr verbreitete Shell ist die der Universität von Californien in Berkeley und wird als BERKELEY - SHELL oder auch C - SHELL bezeichnet. Diese stellt eine beträchtliche Erweiterung der Standard - Shell dar. 07Bourne - Shell
Die Shell als Kommandointerpreter • Die Bourne - Shell ist das Programm, mit dem der Benutzer in der Regel zu-nächst kommuniziert, wenn er UNIX - Kommandos und Benutzerprogramme aufruft. • Neben der einfachen Kommandoausführung stellt sie eine ganze Reihe weiterer, sehr mächtiger Konzepte zur Verführung.. Hierzu gehören eine komplette Kommandosprache mit Variablen, Ablaufstrukturen wie bedingte Ausführungen, Schleifen, unterprogrammähnlicher Aufrufe und Ausnahmebehandlungen. • ! Shell‘s sind in ihrer vollen Mächtigkeit nicht einfach zu erlernen ! • Die Shell ist ein Programm, welches nach dem login standardmäßig gestartet wird und von der startenden Dialogstation solange liest, bis sie ein <enter> - Zeichen sieht. Danach wird sie terminiert, das Betriebssystem meldet dies dem übergeordneten Prozeß. Dieser gibt login aus, wertet die Antwort aus und ruft bei einer gültigen Anmeldung eine neue Shell mit der Umgebung des neuen Benutzer auf 07Bourne - Shell
Die Eingabe, welche die Shell liest, wird von ihr analysiert und danach entweder von ihr selbst ausgeführt oder als Programm gewertet und dieses gestartet. Hierbei untersucht zuvor die Shell noch die Parameter des Programms und expandiert diese, soweit notwendig, nach ihren Regeln. 07Bourne - Shell
Kommandosyntax • Ein Kommando, sei es eine Anwendung an die Shell oder ein Programmaufruf, hat folgende allgemeine Syntax : • kommando_name Parameter_1 parameter_2 ... • Wobei kommando_name der Bezeichner eines Shell - internen Kommandos z.B. : cd oder der Dateiname eines auszuführenden Programms ist z.B.: /etc/mount • Anzahl, Aufbau und Bedeutung der Parameter ist natürlich Kommando und programmierabhängig. • Die einzelnen Parameter werden dabei durch Separatorzeichen getrennt. Normalerweise sind das Leerzeichen, das Tabulatorzeichen und das Zeilenende die gültigen Trennzeichen, diese können jedoch mit Hilfe der Shellvariablen IFS neu definiert werden. 07Bourne - Shell
Die Parametersequenz wird von der Shell auf Metazeichen (*,?,[...]), auf Steuerzeichen (&, &&, |, ||, >, >>, <, <<, (), {}, ;) und zu ersetzende Shellvariablen durchsucht und soweit notwendig expandiert, bevor sie als Programmparameter an das aufgerufene Programm oder Prozedur weitergereicht werden. • Bei der Expandierung werden diese betrachtet und entsprechend ausgewertet • Die Auswertung geschieht wie folgt: • Ersetzung von Shellvariablen ($xxx) durch ihren Wert • Generierung einer Liste von Dateinamen, wobei die Metazeichen interpretiert werden. • * Eine beliebige Zeichenkette • ? Ein beliebiges Zeichen • [...] Eines in den Klammern angegeben Zeichen // Bereiche können in den Klammern angegeben werden durch [<von> - <bis>] oder [a-en-x ...]. • [!...] Keines der in den Klammern angegebene Zeichen 07Bourne - Shell
Soll ein Parameter nicht expandiert werden, so ist er entweder komplett mit Apostroph - Zeichen zu klammern ( ‚parameter‘ ) oder die Zeichen, welche von der Shell falsch interpretiert würden , sind durch das „\“ zu maskieren (z.B.:“echo\?“ liefert „?“ zurück). • Der Parameter kommando_name gibtden Namen des auszuführenden Programms an , soweit es sich nicht um ein Shell - internes Kommando handelt. • Bei einer Kommandoprozedur wird eine neue Shell gestartet, welche die Abarbeitung der Prozedur übernimmt. • Ist kommando_name ein relativer Dateiname, so sucht die Shell nach einer ausführbaren Datei dieses Namens in den Katalogen, die in der Shellvariablen $PATH angegeben sind. Die dort angegebenen Kataloge werden in der vorgegebenen Reihenfolge ( von links nach rechts ) durchsucht, bis eine entsprechende Datei gefunden wird.Sie merkt sich die Position ( im gesamten Dateibaum ) der gefundenen Datei um sie beim nächsten Aufruf schneller erreichen zu können. Haben sich solche Programme geändert, so sollte man die Shell durch eine „hash -r“ Sequenz darüber informieren. • Ist die Suche ergebnislos, so meldet die Shell „xxx: not found“. 07Bourne - Shell
Zum Beispiel: • die aktuelle Datei ist : /usr /name • darin befinden sich folgende Dateien: a a1 ab? abc abc1 append ball bold buch (Katalog , leer) cad_buch (Katalog) cad_buch/kapitel.1 cad_buch/kapitel.2 cad_buch/kapitel.3 cad_buch/kapitel.nunix_buch (Katalog ) • die Parameterseparatoren seien <leerzeichen>, <tab>, <new line> (Standardbelegung) • cat abc gibt die Datei /usr/name/abc aus. Im Gegensatz zu den anderen Erweiterungen wird jedoch nicht der um den Standardkatalog erweiterten Namen an das Programm gegeben. Das Voransetzen des Zugriffspfades beim öffnen der Datei findet im Programm selbst statt und wird vom System vorgenommen. 07Bourne - Shell
echo a* liefert alle Namen der Dateien des betreffendes Kataloges, welche mit dem Buchstaben a beginnen . „ a a1 ab? abc abc1 append“ • echo ab? Liefert alle Namen , die mit ab beginnen und ein weiteres Zeichen haben. „ab? abc “ • echo ab\? Liefert nur „ab?“ • echo cad_buch/kapitel.[1-9] liefret die Dateinamen „ cad_buch/kapitel.1 cad_buch/kapitel.2 cad_buch/kapitel.3 “ • echo * hierbei werden alle oben angeführten Namen außer .profile und .profile1 generiert. • echo .* liefert „. .. .profile .profile1“. Der Name „.“ ist dabei der aktuelle Katalog und „...“ der Vaterkatalog. • echo x* liefert x*, da keine mit x beginnenden Dateien im aktuellen Katalog existieren. • cp [!u]* /tmp kopiert alle Dateien, deren Namen nicht mit u beginnen in den Katalog tmp. Im Beispiel wären dies alle Dateien außer .profile, .profile1 und unix_buch. 07Bourne - Shell
ls -ls *buch* gibt Dateiinformation zu allen Dateien des aktuellen Katalogs aus, in denen die folge buch vorkommt. Dies wäre hier buch, cad_buch, unix_buch. Es dürfen mehrere Metazeichen in einem Namen vorkommen. • Folgende Aufrufe sind gleich cat‘ab?‘, cat ab‘?‘, cat ab\? und cat“ab?“. • Ist eine interaktive Shell bereit, Eingaben vom Benutzer anzunehmen, so zeigt sie dies durch ein Promptzeichen an. • # Super - User - Modus • $ User - Modus • > die Shell benötigt weitere Eingaben. Z.B. weil eine Shellprozedur ein read ausführt. 07Bourne - Shell
Ein - / Ausgabeumlenkung • Vor der Ausführung eines Kommandos können dessen Standardeingabe (Dateideskriptor 0), seine Standardausgabe (Dateideskriptor 1) und die Standardfehlerausgabe (Dateideskriptor 2 ) umgelenkt werden. Die Umlenkung erfolgt durch die Interpretation der Umlenkungsanweisung durch die Shell, ohne dass das Programm dies sieht. Insbesondere ist die Umlenkung nicht in der Parameterzeichenkette enthalten, welche die Shell dem aufgerufenden Programm übergibt. • Die Umlenkung darf in einfachen Kommandos überall vorkommen. • > aus_datei Die Standardausgabe (Dateideskriptor 1) soll die Datei aus_datei sein. Existiert die genannte Datei bereits, so wird sie zuvor auf die Länge 0 gesetzt. Soll die alte Datei erhalten und die neue Ausgabe an deren Ende angehängt werden, so erfolgt dies durch „>>“ 07Bourne - Shell
>> aus_datei Die Standardausgabe wird an die Datei aus_datei angehängt. Existiert die Datei noch nicht, so wird sie neu angelegt. • 2> fehler_datei die Standardfehlerausgabe (dateideskriptor 2) soll in die Datei fehler_datei umgelenkt werden. • >&n diese geht auf die im Dateideskriptor n angegebenen Datei. (seltene Anwendung) • >&- Die Standardausgabe wird geschlossen. • < ein_datei Die Datei soll als Standardeingabe verwendet werden. • <&n Die Standardeingabe liest aus der im Dateideskriptor n angegebenen Datei. • <&- Die Standardeingabedatei wird geschlossen. • Steht hinter dem Kommando ein &, d.h. soll das Kommando als eigenständiger Prozeß im Hintergrund ablaufen, so ist, wenn nicht anders angegeben, die leere Datei ( z.B. hda/dev/null) die Standardeingabe. • Achtung im Dateinamen innerhalb der Ausgabeumlenkung findet keine Namensexpansion statt. z.B. ls > *.c => Datei mit dem Namen „*.c“ 07Bourne - Shell
Kommandoverkettung • Die Shell führt die ihr gegebenen Kommandos normalerweise sequentiell aus. Dabei wird für jedes Kommando ein selbständiger Prozeß gebildet, auf dessen Ende die Shell vor der Ausführung des nächsten Kommando wartet. Soll ein Kommandotext über eine Zeile hinausgehen, so kann das Zeilenende durch das „\“maskiert werden. (durch „\“ wird <new line> wird ignoriert) • Das Semikolon „;“ erfüllt die gleiche Funktion wie <new line> • So können mehrere Kommandos in einer Zeile übergeben werden. kommando_1 {param} ; komando_2 {param} , .... • Jedes Programm liefert einen Funktionswert : den exit Status. Per Konvention ist dies 0, falls das Programm fehlerfrei ablief, ungleich in anderen Fällen. • Achtung: Bei shell-internen Kommandos wird immer 0 als Ergebnis zurückgeliefert! Ist eines der Kommandos der Kommandosequenz ein internes Kommando, so wird beim auftreten eines Fehlers die ganz Sequenz abgebrochen. 07Bourne - Shell
Pipe • Soll in einer Kommandosequenz die Ausgabe des einen Kommandos als Eingabe des nachfolgenden Kommandos benutzt werden; d.h. die Standardausgabe zur Standardeingabe werden, so wird diese mit dem Pipe-Symbol durchgeführt. • kommando_1 {param} | kommando_2 {param} | .... • z.B. „ls | wc -l“ =>gibt die Anzahl der Dateien im aktuellen Katalog aus. ls listet die Datei auf und wc liest diese Ausgabe, zählt die Zeilen darin ( Option -l ) und gibt die Anzahl aus. • Achtung : Wird eines der Kommandos einer Pipekette abgebrochen, so terminieren in der Regel auch die anderen Programme der Kette auf Grund eines Lese oder Schreibfehlers bei Operationen auf der Pipe. 07Bourne - Shell
Shellvariablen • Die Kommandosprache der Shell erlaubt neben den bisher aufge-führten Kommandoelementen auch Variablen, deren Werte Strings sind. Mit Hilfe spezieller Funktionen( z.B. expr ) kann eine Zeichenkette jedoch auch als numerischer oder logischer Wert interpretiert werden. • Die Bezeichner (Namen)der Shellvariablen bestehen aus Buchstaben, gefolgt von Buchstaben, Ziffern und dem Unterstreichungszeichen. • Ist in einer Anweisung der wert einer Variablen gemeint, so wird dem Variablennamen ein $ vorangesetzt. • name=wert • Achtung: Diese Sequenz ist ohne Zwischenraum zu schreiben. Kommen in der zuzuweisenden Zeichenkette Leerzeichen etc. vor so ist diese in Anführungszeichen zu setzen. • name=„wert abc_2 stv“ 07Bourne - Shell
Das Kommando echo $name • zeigt den Wert der Variablen name an. Das Kommando“set“ ohne Parameter gibt die in der aktuellen Umgebung definierten Shellvariablen aus. • z.B. pas=„pc -o t t.p“ => weist der (neu definierten ) Shellvariablen pas die Zeichenkette „pc -o t t.p“ zu. $pas<cr> entspricht der Eingabe von „pc -o t t.p<cr>“ . o=/usr/name/cad_buch/kapitel.1 => weist der Variablen o die o.g. Zeichenkette zu. pr $o <=> “pr /usr/name/cad_buch/kapitel.1“ • Sollen der einzusetzenden Variablen (Parameter) unmittelbar ein oder mehrere Zeichen folgen, so ist der Variablenname mit {...} zu klammern So bedeutet „${ab}c“ z.B.: „Der Wert der Variablen ab direkt gefolgt von c“, während mit „$abc“ der Wert der variablen abc gemeint ist. 07Bourne - Shell
Gültigkeitsbereiche von Shellvariablen • In Unix unterscheidet man zwischen lokalen und globalen Variablen. Zunächst sind alle Variablen lokal, d.h. gelten nur in der aktuellen Shell-Umgebung als deklariert und mit einem Wert versehen. Beim Aufruf einer weiteren Shellprozedur oder durch Beendigung der aktuellen Prozedur verlieren die variablen ihre Gültigkeit. Dies gilt auch für Shell interne Variablen ( $0,...,$n). • Soll eine aufgerufene Prozedur auf bestimmte Variablen der aufrufenden Prozedur zurückgreifen , so müssen dies mittels export variable... in die neue Umgebung exportiert werden. Dieses ist nicht möglich für die shell-internen Parameter! • In großen Kommandoprozeduren kann es sinnvoll sein, Variablen die nicht mehr benötigt werden, zu löschen. Dies ist mit dem Befehl unset- möglich. 07Bourne - Shell
Ablaufsteuerung • Für die Ablaufsteuerung einer Shellprozedur sind folgende Möglichkeiten vorhanden: • { kommando_folge;} • ( kommando_folge ) • name() { kommando_folge;} • if kommando_folge_1 ; then kommando_folge_2 {elif kommando_folge_3 ; then kommando_folge} {else kommando_folge_3 } fi • for name ; do kommando_liste ; done • for name in worte ; do kommando_liste ; done • while kommando_liste_1 ; do kommando_liste_2 ; done • until kommando_liste_1 ; do kommandoliste_2 ; done • case wort in muster{|muster ...}) kommando_liste ;;... ; esac 07Bourne - Shell
Für die angeführten Kommandos müssen die Kommandowörter ( if then else fi for do done while until case in esac ) jeweils als erstes Wort eines Kommandos erscheinen. Dies bedeutet, sie müssen entweder als erstes Wort einer neuen Zeile oder als erstes Wort hinter einem“;“ stehen. • kommando_folge bezeichnet ein oder mehrere Kommandos, wobei diese durch eine PIPE oder durch ein sequentielles Ausführungs-zeichen („;“ „&&“ „||“) verknüpft sind. 07Bourne - Shell
Kommandoklammerung • Die Shell kennt zwei Arten der Klammerung ( „(...)“ „{...}“ ). • Bei der „{...}“ Form werden die Kommandos zwischen den Klammern einfach ausgeführt. Die Klammern stellen wie in C eine Art begin -end - Block dar. Es ist dabei zu beachten, dass die letzte Anweisung in der Klammer durch ein „ ; “ oder eine neue Zeile abgeschlossen werden muss. • In der „(...)“ Form kann eine Folge von Kommandos zusammengefaßt und als eigenständiger Prozeß abgearbeitet werden. Nachfolgende Angaben wie & oder Ein- oder Ausgabeumlenkung sind dann für die ganze Gruppe gültig. • z.B. : cd /usr/martin ; sort -u *.tel | tee telefon; lpr telefon • Diese Anweisung sortiert in dem Katalog /usr/martin alle Dateien mit der Endung .tel in eine neue Datei Telefon und gibt dies auf den Drucker aus. Das cd- Kommando ist nur innerhalb der klammer gültig. Nach der Ausführung steht der aktuelle Katalog noch auf dem alten Wert. 07Bourne - Shell
Funktionsdefinition • name () {kommando_folge ;} • Mit dieser Anweisung wird die Funktion name die in {...} geklammerte Kommandofolge zugeordnet. Durch den Aufruf von name kann nun die Ausführung von kommando_folge aufgerufen werden, in der Art wie man eine Funktion oder Unterprogramm aufruft. • Werden beim Aufruf von name Parameter mitgegeben, so stehen dies entsprechend in der Kommandofolge als $1, $2 usw. zur Verführung. • ! Achtung : $0 enthält jedoch den Namen der ausführenden Shell. Die Funktionsdefinition kann mit „unset name“ deaktiviert werden. • Z.B. : wo () {pwd ; who am i; ls $* ; } • Einführung eines neuen Kommandos, das den aktuellen Katalog, den Benutzernamen und den Inhalt des aktuellen Katalogs ausgibt. 07Bourne - Shell
if - then / else - fi / elif • if kommando_folge_1 then kommando_folge_2 { else kommando_folge3 } fi • In dieser Konstruktion wird die kommando_folge_2 nur dann ausge-führt, wenn die kommando_folge_1 als Resultat 0 liefert. • Ist der else-Teil vorhanden, so wird die dort angegebene kommando_folge_3 dann ausgeführt, wenn das Ergebnis von kommando_folge_1 nicht gleich 0 war. • Die if-Konstruktion kann durch ... elif ... weitergeschachtelt werden. • Z.B. : if cc -c teil2.c then ld -o prog teil1.o teil2.o else echo „Fehler beim übersetzen“ fi • Hier wird die datei teil2.c übersetzt aber nicht automatisch gebunden, ( Optio „-c“ ). 07Bourne - Shell
Findet ccbeim übersetzen keine Fehler, so liefert cc den Exit-Status „0“ zurück. In diesem fall wird das Binden ( ld ...) durchgeführt, andernfalls die Meldung „ Fehler beim Übersetzen“ ausgegeben. • - nächstes Beispiel kopieren : • if test $#-eq 0 then echo „Kopie von :“ read von echo „nach .“ read nach elif test $# -eq 1 then echo „Kopie von „ $1 „nach :“ read nach von=$1 else von=$1; nach=$2 fi cp $von $nach • Dieses Programm ist ein einfache Kopierprozedur. Wird die Prozedur ohne Parameter aufgerufen, so wird gefragt, von wo kopiert werden soll (read liest von der Standardeingabe und weist den Text der nächsten Shellvariablen zu ). 07Bourne - Shell
Danach wird nach dem Ziel gefragt. Wurde beim Aufruf ein Parameter angegeben ($# -eq 1 ), so wird nach dem Ziel gefragt. Sind zwei oder mehr Parameter angegeben, so wird der erste Parameter als Quelle betrachtet und der zweite als Ziel. Alle anderen Parameter werden nicht beachtet. • Eine if- Anweisung kann auch anders dargestellt werden. Dies geschieht mit hilfe der Zeichen && für „Falls 0“ und || für „Falls !=null“. • kommando_liste_1 && kommando_liste_2 und kommando_liste_1 || kommando_liste_2 • Bei && wird die zweite Kommandoliste nur dann ausgeführt, wenn die kommando_liste_1 fehlerfrei abläuft, bei || nur dann , wenn die kommando_liste_1 einen Wert != 0 liefert. • z.B. : cc -c prog.c && ld -o versuch prog.o mod1.o mod2.o -lc • Hierbei wird die Quelle prog.c mit Hilfe des C-Kopilers übersetzt. Nur wenn dies Übersetzung fehlerfrei abläuft wird der Rest gestartet ( ld ...). • Da Vergleiche sehr oft vorkommen wurden aus Effizienzgründe das test-Kommando fest in die Shell eingebaut ( [...] ). • z.B. : if test §# -eq 3 und if [$# -eq 3] Die beiden Ausdrücke erfüllen die gleiche Funktion. 07Bourne - Shell
Kommandoschleifen • Die Bourne-Shell kennt drei Arten von Kommandoschleifen : • Die for-Schleife, deren Körper pro Parameter bzw Wort der Wortliste einmal durchlaufen wird. • Die while-Schleife, deren Rumpf solange durchlaufen wird,wie die while-Bedingung erfüllt ist. • Die until-Schleife, deren Körper solange durchlaufen wird, wie die until-Bedingung erfüllt ist. • In diesen Formen einer Schleife sind die Anweisungen continue und break möglich. Bei continue wird der Rest der Schleife übersprungen und die Schleifenbedingung erneut geprüft. Mit break wird Die Schleife beendet und die Abarbeitung hinter der Schleife ( nach dem done ) fortgesetzt. Beide Kommandos erlauben einen Parameter n, der einen Sprung aus geschachtelten Schleifen zuläßt. 07Bourne - Shell
FOR - Schleife • Die Konstruktion A: • for name do kommando_liste done • Diese Anwendung erlaubt eine wiederholte Ausführung der Kommandoliste, wobei der Variablen name nacheinander die werte der Variablen $1 bis $n zugewiesen werden. Die Schleife wird somit $# mal durchlaufen. • Z.B. : for i do cc -c ${i}.c done • Beim Aufruf braucht nicht der volle Name der c- Quelltextdatei über-geben zu werden sondern nur der vordere Teil. Die Endung .c wird automatisch an den Namen angehängt. 07Bourne - Shell
Die Konstruktion B: • for name in wort ... do kommando_liste done • Hierbei nimmt die Variable name nacheinander alle Werte an, die an der Stelle wort ... aufgeführt sind. Die Kommandoliste wird entsprechend so oft durchlaufen, wie wort ... Wörter besitzt. • z. B. : Lösche der temporären Dateien for i in /tmp /usr /tmp /user /tmp do rm -rf $i/* done • Hier wird der Schleifen körper dreimal druchlaufen, wobei $i nacheinanderdie Werte /tmp, /usr/tmp, /user/tmp annimmt. Es werden alleDateien in den Katalogen /tmp, /usr/tmp und /user/tmp gelöscht. 07Bourne - Shell
WHILE - Schleife • Die Konstruktion : • while kommando_liste_1 do kommando_liste_2 done • Hier wird die kommando_liste_1 ausgeführt. Ist ihr Ergebnis 0, so wird die kommando_liste_2 ausgeführt. Dieser Vorgang geschieht solange, bis kommando_liste_1 einen von 0 verschiedenen Wert liefert. In diesem Fall wird die Abarbeitung hinter der done-Anweisung fortgesetzt. Die schleife kann auch durch eine break-Anweisung verlassen werden. • Im nächste Beispiel wird der freie Speicherplatz aller angeschlossenen Geräte in kbyte ausgegeben. Der Befehl /etc/mount gibt für jedes angeschlossene Dateisystem eine Information aus (z.B. : „/dev/rl0 on /usr“). Die Ausgabe wird über eine Pipe in den zweiten Shellprozeß („(...)“) umgelenkt. 07Bourne - Shell
Beispiel : Ausgabe freien Speicherplatz angeschlossener Geräte #!/bin/sh /etc/mount | ( while read ger1 ger2 ger3 ger4 # /angegebenen parametern do set `df $ger1|tail -1` kbyte=`expr $5 / 2` echo -n "$ger1 im Katalog $ger3 hat $kbyte" if test `expr $5 % 2` -eq "0"; then teil=",0"; else teil=",5" fi echo "$teil kbyte frei" done ) • In diesem Vorgang liest read von der Standardeingabe und weist die Wörter einer Eingabezeile nacheinander den angegebenen Parametern zu. $ger1 ist der Gerätename und $ger3 der Katalog, in welchen das Dateisystem montiert ist. read liefert beim erreichen von <eof> einen von 0 verschiedenen Wert. Die while-Schleif wird somit für jedes angeschlossene Gerät einmal durchlaufen. Das df-Kommando gibt die Anzahl der freien Blöcke des Gerätes zurück. Set weist diese Ausgabe den Positionsparmetern zu. $2 erhält dabei die Anzahl der freien Blöcke ( zu 512 Byte). Dieser Wert wird nun durch 2 dividiert und der Variablen kbyte zugewiesen. 07Bourne - Shell
Mit echo wird nun der 1.Teil der Information ausgegeben. Die Option -n unterdrückt <new line> nach der Meldung. Jetzt wird berechnet, ob noch „,0“ oder „,5“ an die kbyte-Angabe anzuhängen sind (%-Moduloberechnung ) und der Rest der Information auszugeben. Die Verwendung der `...` -Klammern bei df und expr bewirkt, daß das jeweilige Kommando ausgeführt und der text der Standardausgabe des Kommandos als Ergebnis eingesetzt wird. 07Bourne - Shell
UNTIL - Schleife • Die until-Schleife stellt die Umkehrung der while-Schleife dar. • Die Konstruktion : • until kommando_liste_1 ;do kommando_liste_2 ;done • Hierbei wird der Schleifenrumpf solange ausgeführt, wie kommando_liste_1 das Ergebnis falsch ( !=0) liefert. • Z.B. : Verwaltung eines Laserdruckers. • Der Prozeß wird beim Systemstart als Hintergrundprozeß gestartet und wartet ständig auf Aufträge. Ein Auftrag kann dadurch erteilt werden, daß ein Benutzer eine Datei in den Katalog (z.B. : /usr/auftrag ) anlegt. Der Dateiname des Auftrages darf nur einmal vorkommen. Ein solcher Name wird gebildet das man in einer Shellprozedur und aus der Prozeßnummer einen Namen zusammensetzt. 07Bourne - Shell
# Beispiel Verwaltung Drucker #!/bin/sh -x cd /vol/fileserv1/usr1/stud/4/s680734/auftrag while true do until set Auf* test $1 != 'Auf*' do sleep 5 done for i do # Bearbeitung des Druckauftrages in $i rm $i done done • Die äußere Schleife ist eine Endlosschleife da true immer den Wert 0 zurückliefert. In der until Schleife werden mit „ set * “ den Positions-Parametern $0, $1, ... Die Namen der Datei in dem Katalog /.../auftrag zugewiesen. Ist keine Datei vorhanden , so wird „*“ zurückgegeben und „test $1 != `*`“ liefert falsch. In diesem Fall legt sich der Prozeß 5 sec schlafen und versucht es dann erneut. Sind Dateien vorhanden, so wird angenommen, dass dies Aufträge sind; sie werden bearbeitet und danach gelöscht. 07Bourne - Shell
Sprunganweisung mit CASE • Die case - Konstruktion erlaubt, eine Sprunganweisung in einer Shell-prozedur aufzubauen. • Die Konstruktion : • case wort in muster_1 ) kommando_liste1;; { muster_liste2 ) kommando_liste_2 ;; ... } esac • Die Zeichenkette Wort wird dabei in der Reihenfolge der Anweisungen mit den vorgegebenen Mustern muster_1, muster_2 usw verglichen, und bei Übereinstimmung wird die nachfolgende Kommandoliste ausgeführt. Es dürfen auch mehrere durch „|“ getrennte Muster in einer Zeile vor dem „)“ vorkommen. • Muster_1 | muster_2 ... ) kommando_liste ;; • Das Zeichen „|“ steht dabei für oder. In den Mustern sind die Metazeichen * ? [] mit der üblichen Bedeutung erlaubt.. 07Bourne - Shell
In der Sequenz : „ *) kommando_liste ;; “ • kann somit eine Liste angegeben werden,die ausgeführt wird, wenn keines der vorstehenden Muster zutrifft. • z.B. : Die nachfolgende Prozedur steht in der Datei l : • if test $# -eq 0 then ls -ls elsecase $1 in -all) opt=„-lsiR“ ; shift ;; -short) shift ;; -*) opt=$1 ; shift ;; esac ; ls $opt $@ ; fi • Diese Anweisung stellt eine Kurzversion des ls-Kommandos dar. Ohne Parameter aufgerufen gibt sie ein Inhaltsverzeichnis des aktuellen Katalogs unter Verwendung der Option -ls aus. Ist der erste Parameter -all, so wird die ls-Option „-lsiR“ eingesetzt; bei -short ist dies keine Option. In allen anderen Fällen, in denen der erste Parameter mit „-“ beginnt, wird genau dieser als Option eingesetzt. shift sorgt dafür, daß alle Parameter um eine Position nach vorne rücken, d.h. $2 wird zu $1, $3 zu $2 usw ... 07Bourne - Shell