Viele Aenderungen

This commit is contained in:
rschaten
2004-12-02 13:54:06 +00:00
parent c0e556e25d
commit 15af99f29e
10 changed files with 873 additions and 57 deletions

View File

@ -2,27 +2,31 @@
\chapter{Wie sieht ein Shell-Skript aus?}
Wie schon erw<72>hnt, kann ein Shell-Skript beinahe alles, was eine `richtige'
Programmiersprache auch kann. Bei der Entwicklung sollte man nur bedenken, da<64>
gerade die Ausf<EFBFBD>hrung von externen Kommandos~--~und das ist eine der
Standard-Techniken bei der Shell-Programmierung~--~nur sehr langsam vonstatten
geht. F<>r Anwendungen bei denen z. B. viele Rechnungen oder Stringbearbeitungen
gemacht werden m<>ssen, sollte man also ggf. die Benutzung einer anderen
Sprache, beispielsweise Perl\index{Perl}, in Erw<72>gung ziehen.
gerade die Aus\-f<EFBFBD>h\-rung von externen Kommandos~--~und das ist eine der
Standard-Techniken bei der Shell-Pro\-gram\-mie\-rung~--~nur sehr langsam
vonstatten geht. F<>r Anwendungen bei denen z. B. viele Rechnungen oder
Stringbearbeitungen gemacht werden m<>ssen, sollte man also ggf. die Benutzung
einer anderen Sprache, beispielsweise Perl\index{Perl}, in Erw<72>gung ziehen.
In der Shell stehen viele Mechanismen zur Verf<72>gung, die auch aus anderen Sprachen bekannt sind. Um den Umfang dieses Dokuments nicht zu sprengen, werden an dieser Stelle nur die wichtigsten vorgestellt.
\section{Grunds<EFBFBD>tzliches}
\section{HowTo}
Zun<EFBFBD>chst soll die Frage gekl<6B>rt werden, wie man <20>berhaupt ein ausf<73>hrbares Shell-Skript schreibt. Dabei wird vorausgesetzt, da<64> dem Benutzer der Umgang mit mindestens einem Texteditor\index{Texteditor} (\texttt{vi}\index{vi=\texttt{vi}}, \texttt{emacs}\index{emacs=\texttt{emacs}} etc.) bekannt ist.
Zun<EFBFBD>chst soll die Frage gekl<6B>rt werden, wie man <20>berhaupt ein ausf<73>hrbares
Shell-Skript schreibt. Dabei wird vorausgesetzt, da<64> dem Benutzer der Umgang
mit mindestens einem Texteditor\index{Texteditor}
(\texttt{vi}\index{vi=\texttt{vi}}, \texttt{emacs}\index{emacs=\texttt{emacs}}
etc.) bekannt ist.
Bei der Erstellung oder Bearbeitung von Shell-Skripten mu<6D> darauf geachtet
werden, da<64> sich keine CR/LF-Zeilenumbr<62>che einschleichen, wie dies leicht bei
der Benutzung von MS-DOS bzw. Windows-Systemen zur Bearbeitung von Skripten
<EFBFBD>ber das Netzwerk passieren kann.
\subsection{HowTo}
Zun<EFBFBD>chst mu<6D> mit Hilfe des Editors eine Textdatei angelegt werden, in die der `Quelltext' geschrieben wird. Wie der aussieht, sollte man anhand der folgenden Abschnitte und der Beispiele im Anhang erkennen k<>nnen. Beim Schreiben sollte man nicht mit den Kommentaren\index{Kommentar} geizen, da ein Shell-Skript auch schon mal sehr unleserlich werden kann.
Zun<EFBFBD>chst mu<6D> mit Hilfe des Editors eine Textdatei angelegt werden, in die der
`Quelltext' geschrieben wird. Dabei mu<6D> darauf geachtet werden, da<64> sich keine
CR/LF-Zei\-len\-um\-br<EFBFBD>\-che einschleichen, wie dies leicht bei der Benutzung
von MS-DOS bzw. Windows-Systemen zur Bearbeitung von Skripten <EFBFBD>ber das Netzwerk
passieren kann. Wie der Quelltext aussieht, sollte man anhand der folgenden
Abschnitte und der Beispiele im Anhang erkennen k<>nnen. Beim Schreiben sollte
man nicht mit den Kommentaren\index{Kommentar} geizen, da ein Shell-Skript auch
schon mal sehr unleserlich werden kann.
Nach dem Abspeichern der Datei unter einem geeigneten Namen\footnote{Bitte
\emph{nicht} den Namen \texttt{test}\index{test=\texttt{test}} verwenden. Es
@ -32,25 +36,16 @@ ausgef
zugleich einer der verwirrendsten Anf<6E>ngerfehler. Mehr zu dem
\texttt{test}-Kommando unter \ref{bedingungen}.} mu<6D> die sie ausf<73>hrbar gemacht
werden. Das geht mit dem Unix-Kommando
\texttt{chmod}\index{chmod=\texttt{chmod}}. Rechte k<>nnen unter Unix getrennt
f<EFBFBD>r den Benutzer (user, \texttt{u}), die Gruppe (group, \texttt{g}) oder andere
(others, \texttt{o}) vergeben werden. Au<41>erdem kann man die Rechte f<>r alle
Gruppen zusammen (all, a) setzen. Man kann getrennt die Rechte f<>r das lesen
(read, \texttt{r}), das schreiben (write, \texttt{w}) und die Ausf<73>hrung
(execution, \texttt{x}) vergeben. Damit die Datei f<>r einen Benutzer wirklich
ausf<EFBFBD>hrbar ist, mu<6D> er das Lese- und das
Ausf<EFBFBD>hrungsrecht\index{Aus<EFBFBD>hrungsrecht} haben. Um die Rechte zu setzen, mu<6D> man
\texttt{chmod} in Parametern mitgeben, worauf sich das Kommando bezieht, ob das
Recht gesetzt (\texttt{+}) oder weggenommen (\texttt{-}) werden soll, und
welche Rechte gemeint sind. Damit alle Benutzer das Skript ausf<73>hren d<>rfen,
benutzt man das Kommando \texttt{chmod ugo+rx name} oder einfach \texttt{chmod
+rx name}. Mit \texttt{chmod u+x name} hat nur der Besitzer der Datei
Ausf<EFBFBD>hrungsrechte.
\texttt{chmod}\index{chmod=\texttt{chmod}} und wird in Abschnitt \ref{chmod}
ausf<EFBFBD>hrlich beschrieben. An dieser Stelle reicht uns ein Aufruf in der Form
\texttt{chmod 755 dateiname}, um das Skript f<>r alle Benutzer ausf<73>hrbar zu
machen.
Um ein Shell-Skript ausf<73>hren zu k<>nnen braucht es aus der Sicht des
ausf<EFBFBD>hrenden Benutzers mindestens die Rechte zum Lesen (r) und Ausf<73>hren (x).
Dann kann das Skript gestartet werden. Da sich aus Sicherheitsgr<67>nden auf den meisten Systemen das aktuelle Verzeichnis nicht im Pfad des Benutzers befindet, mu<6D> man der Shell noch mitteilen, wo sie zu suchen hat: Mit \texttt{./name} wird versucht, im aktuellen Verzeichnis (\texttt{./}) ein Programm namens \texttt{name} auszuf<75>hren.
Dann kann das Skript gestartet werden. Da sich aus Sicherheitsgr<67>nden auf den
meisten Systemen das aktuelle Verzeichnis nicht im Pfad des Benutzers befindet,
mu<EFBFBD> man der Shell noch mitteilen, wo sie zu suchen hat: Mit \texttt{./name}
wird versucht, im aktuellen Verzeichnis (\texttt{./}) ein Programm namens
\texttt{name} auszuf<75>hren.
Auf den meisten Systemen befindet sich im Pfad ein Verweis auf das Verzeichnis
\texttt{bin} unterhalb des Home-Verzeichnisses eines Benutzers. Das bedeutet
@ -60,7 +55,7 @@ kann man an der Shell durch Eingabe von \texttt{echo
\$PATH}\index{\$PATH=\texttt{\$PATH}} herausfinden.
\subsection{R<EFBFBD>ckgabewerte}\label{exitcode}\index{R<EFBFBD>ckgabewert|(textbf}\index{Exit-Code|see{R<EFBFBD>ckgabewert}}\index{Exit-Status|see{R<EFBFBD>ckgabewert}}
\section{R<EFBFBD>ckgabewerte}\label{exitcode}\index{R<EFBFBD>ckgabewert|(textbf}\index{Exit-Code|see{R<EFBFBD>ckgabewert}}\index{Exit-Status|see{R<EFBFBD>ckgabewert}}
Wenn unter Unix ein Proze<7A> beendet wird, gibt er einen R<>ckgabewert (auch
Exit-Code oder Exit-Status genannt) an seinen aufrufenden Proze<7A> zur<75>ck. So
@ -281,7 +276,9 @@ Ausdruck}}\index{Ausdruck|see{Regul
wesentlich mehr M<>glichkeiten als die relativ einfachen Wildcards f<>r
Dateinamen.
In der folgenden Tabelle wird gezeigt, in welchen Unix-Tools welche Zeichen zur Verf<72>gung stehen. Eine ausf<73>hrlichere Beschreibung der Eintr<74>ge findet sich auf Seite \pageref{beschreibung_der_muster}. \nopagebreak
In der folgenden Tabelle wird gezeigt, in welchen Unix-Tools welche Zeichen zur
Ver\-f<EFBFBD>\-gung stehen. Eine ausf<73>hrlichere Beschreibung der Eintr<74>ge findet sich
auf Seite \pageref{beschreibung_der_muster}. \nopagebreak
\LTXtable{\textwidth}{tab_mustererkennung_muster.tex}
Bei einigen Tools (\texttt{ex}, \texttt{sed} und \texttt{ed}) werden zwei Muster angegeben: Ein Suchmuster (links) und ein Ersatzmuster (rechts). Nur die folgenden Zeichen sind in einem Ersatzmuster g<>ltig:\nopagebreak
@ -358,6 +355,54 @@ F
\index{Arithmetik-Expansion|)}
\section{Eltern und Kinder: Proze<7A>ordnung\label{prozessordnung}\index{Prozess|(textbf}\index{PID|see{Prozess}}\index{Parent-Prozess|see{Prozess}}\index{PPID|see{Prozess}}\index{Subshell|(textbf}}
Jedes laufende Programm auf einem Unixoiden System besteht aus einem oder
mehreren Prozessen, die jeweils eine eigene Proze<7A>-ID (PID) haben. Erzeugt ein
Programm mehrere Prozesse, sind die zu einer Proze<7A>gruppe zusammengefa<66>t. Jeder
laufende Proze<7A>\footnote{Es gibt eine Ausnahme: der Init-Proze<7A>, der immer die
PID 1 hat, hat keine Eltern. Er stammt direkt vom Kernel ab.} verf<72>gt <20>ber
genau eine Parent-Proze<7A>-ID (PPID). Das ist die ID des Prozesses, der den
jeweiligen Proze<7A> erzeugt hat. Man spricht in diesem Zusammenhang tats<74>chlich
von Eltern- bzw. Kind-Prozessen.
Diese Zusammenh<6E>nge lassen sich sehr sch<63>n durch die Ausgabe des Kommandos
\texttt{pstree} oder \texttt{ps -efH} darstellen, letzteres zeigt auch gleich
die PIDs und die PPIDs an.
Wenn in einer Shell ein Kommando gestartet wird, ist es ein Kind dieser Shell.
Wird ein Skript gestartet, <20>ffnet es sich seine eigene Shell (siehe
\ref{auswahl_der_shell}) und f<>hrt sich innerhalb dieser aus. Die Shell des
Skriptes ist dabei ein Kind der interaktiven Shell, die einzelnen Kommandos des
Skriptes sind Kinder der Skript-Shell.
Eine solche Shell-in-Shell-Umgebung wird `Subshell' genannt, dieser
Mechanismus~--~und somit auch der Begriff~--~tauchen immer wieder auf.
Wichtig in diesem Zusammenhang ist das Verst<73>ndnis f<>r die Vererbung zwischen
den beteiligten Prozessen. Wenn in einer Shell eine Variable definiert und
exportiert wird, existiert diese auch f<>r die Kind-Prozesse. Gleiches gilt
beispielsweise f<>r einen Verzeichnis-Wechsel. Umgekehrt gilt dies nicht: ein
Proze<EFBFBD> kann die Umgebung des Parent-Prozesses nicht ver<65>ndern. Das geschieht
nicht zuletzt aus Sicherheitsgr<67>nden so.
Will man die <20>nderungen eines Skriptes <20>bernehmen~--~beispielsweise wenn ein
Skript die Benutzerumgebung konfigurieren soll (.bashrc, .profile und
Konsorten)~--~mu<6D> das explizit angefordert werden. Dazu ruft man es mit einem
vorangestellten \texttt{source}\index{source=\texttt{source}} bzw. in der
Kurzform mit einem vorangestellten Punkt auf. Weiteres zu dem Thema findet sich
im Abschnitt \ref{source}.
Besonders mu<6D> man diesen Umstand im Hinterkopf behalten, wenn mit
Pipelines\index{Pipe} (siehe Abschnitt \ref{befehlsformen}) gearbeitet wird.
Dabei werden auch Kommandos in Subshells ausgef<65>hrt, was dann dazu f<>hrt da<64>
Variablen belegt werden die dann nach Ausf<73>hrung der Pipeline pl<70>tzlich wieder
leer sind. Die Abschnitte \ref{subshellschleifen} und \ref{daten_hochreichen}
widmen sich diesem mitunter recht <20>rgerlichen Thema.
\index{Prozess|)}\index{Subshell|)}
\section{Programmablaufkontrolle}
Bei der Shell-Programmierung verf<72>gt man <20>ber <20>hnliche Konstrukte wie bei anderen Programmiersprachen, um den Ablauf des Programms zu steuern. Dazu geh<65>ren Funktionsaufrufe, Schleifen, Fallunterscheidungen und dergleichen.\nopagebreak