nderungsvorschlge von Kai Thne eingebaut
This commit is contained in:
@ -8,6 +8,11 @@ In der Shell stehen viele Mechanismen zur Verf
|
||||
|
||||
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.
|
||||
@ -35,6 +40,9 @@ 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.
|
||||
|
||||
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.
|
||||
|
||||
Auf den meisten Systemen befindet sich im Pfad der Eintrag \texttt{\~{}/bin} bzw. \texttt{/home/benutzername/bin}, das bedeutet da<64> man Skripte die immer wieder benutzt werden sollen dort ablegen kann, so da<64> sie auch ohne eine Pfadangabe gefunden werden. Wie der Pfad genau aussieht kann man an der Shell durch Eingabe von \texttt{echo \$PATH}\index{\$PATH=\texttt{\$PATH}} herausfinden.
|
||||
@ -44,7 +52,16 @@ Auf den meisten Systemen befindet sich im Pfad der Eintrag \texttt{\~{}/bin} bzw
|
||||
|
||||
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 kann der Mutterproze<7A> kontrollieren, ob die Ausf<73>hrung des Tochterprozesses ohne Fehler beendet wurde. In einigen F<>llen (z. B. \texttt{grep}\index{grep=\texttt{grep}}) werden unterschiedliche Exit-Codes f<>r unterschiedliche Ereignisse benutzt.
|
||||
|
||||
Dieser R<>ckgabewert wird bei der interaktiven Benutzung der Shell nur selten benutzt. Aber in der Programmierung von Shell-Skripten ist er von unsch<63>tzbarem Wert. So kann das Skript automatisch entscheiden, ob bestimmte Aktionen ausgef<65>hrt werden sollen, die von anderen Aktionen ab\-h<EFBFBD>n\-gen. Beispiele dazu sieht man bei der Beschreibung der Kommandos \texttt{if}\index{if=\texttt{if}} (\ref{if}), \texttt{case}\index{case=\texttt{case}} (\ref{case}), \texttt{while}\index{while=\texttt{while}} (\ref{while}) und \texttt{until}\index{until=\texttt{until}} (\ref{until}), sowie in dem Abschnitt <20>ber Befehlsformen (\ref{befehlsformen}).
|
||||
Dieser R<>ckgabewert wird bei der interaktiven Benutzung der Shell nur selten
|
||||
benutzt, da Fehlermeldungen direkt vom Benutzer abgelesen werden k<>nnen. Aber
|
||||
in der Programmierung von Shell-Skripten ist er von unsch<63>tzbarem Wert. So kann
|
||||
das Skript automatisch entscheiden, ob bestimmte Aktionen ausgef<65>hrt werden
|
||||
sollen, die von anderen Aktionen ab\-h<EFBFBD>n\-gen. Beispiele dazu sieht man bei der
|
||||
Beschreibung der Kommandos \texttt{if}\index{if=\texttt{if}} (\ref{if}),
|
||||
\texttt{case}\index{case=\texttt{case}} (\ref{case}),
|
||||
\texttt{while}\index{while=\texttt{while}} (\ref{while}) und
|
||||
\texttt{until}\index{until=\texttt{until}} (\ref{until}), sowie in dem
|
||||
Abschnitt <20>ber Befehlsformen (\ref{befehlsformen}).
|
||||
|
||||
In der Bourne-Shell wird der Exit-Code des letzten aufgerufenen Programms in der Variable \texttt{\$?}\index{\$?=\texttt{\$?}} abgelegt. <20>blicherweise geben Programme den Wert 0 zur<75>ck, bei irgendwelchen Problemen einen von 0 verschiedenen Wert. Das wird im folgenden Beispiel deutlich:
|
||||
\LTXtable{\textwidth}{tab_beisp_exitcode.tex}
|
||||
@ -84,7 +101,18 @@ Die wichtigsten eingebauten Shell-Variablen sind:\nopagebreak
|
||||
\section{Variablen-Substitution}\index{Variablen>-Substitution|(textbf}\index{Substitution|see{Variablen-Subst.}}\index{Variablen|(textbf}
|
||||
\index{!==\texttt{!=}|(textbf}\index{\$\{Variable\}=\texttt{\$\{}\textsl{Variable}\texttt{\}}|(textbf}\index{\$\{Variable:-Wert\}=\texttt{\$\{}\textsl{Variable}\texttt{:-}\textsl{Wert}\texttt{\}}|(textbf}\index{\$\{Variable:=Wert\}=\texttt{\$\{}\textsl{Variable}\texttt{:=}\textsl{Wert}\texttt{\}}|(textbf}\index{\$\{Variable:?Wert\}=\texttt{\$\{}\textsl{Variable}\texttt{:?}\textsl{Wert}\texttt{\}}|(textbf}\index{\$\{Variable:+Wert\}=\texttt{\$\{}\textsl{Variable}\texttt{:+}\textsl{Wert}\texttt{\}}|(textbf}
|
||||
|
||||
Unter Variablen-Substitution versteht man verschiedene Methoden um die Inhalte von Variablen zu benutzen. Das umfa<66>t sowohl die einfache Zuweisung eines Wertes an eine Variable als auch einfache M<>glichkeiten zur Fallunterscheidung. In den fortgeschritteneren Shell-Versionen (\texttt{bash}\index{Bourne-Again-Shell}, \texttt{ksh}\index{Korn-Shell}) existieren sogar M<>glichkeiten, auf Substrings von Variableninhalten zuzugreifen. In der Standard-Shell benutzt man f<>r einfache Aufgaben <20>blicherweise Tools wie \texttt{cut}, \texttt{basename}\index{basename=\texttt{basename}} oder \texttt{dirname}; komplexe Bearbeitungen erledigt der Stream-Editor \texttt{sed}\index{sed=\texttt{sed}}. Einleitende Informationen dazu finden sich im Kapitel <20>ber die Mustererkennung (\ref{mustererkennung}).
|
||||
Unter Variablen-Substitution versteht man verschiedene Methoden um die Inhalte
|
||||
von Variablen zu benutzen. Das umfa<66>t sowohl die einfache Zuweisung eines
|
||||
Wertes an eine Variable als auch einfache M<>glichkeiten zur Fallunterscheidung.
|
||||
In den fortgeschritteneren Shell-Versionen
|
||||
(\texttt{bash}\index{Bourne-Again-Shell}, \texttt{ksh}\index{Korn-Shell})
|
||||
existieren sogar M<>glichkeiten, auf Substrings von Variableninhalten
|
||||
zuzugreifen. In der Standard-Shell benutzt man f<>r einfache Aufgaben
|
||||
<EFBFBD>blicherweise Tools wie \texttt{cut},
|
||||
\texttt{basename}\index{basename=\texttt{basename}} oder \texttt{dirname};
|
||||
komplexe Bearbeitungen erledigt der Stream-Editor
|
||||
\texttt{sed}\index{sed=\texttt{sed}}. Einleitende Informationen dazu finden
|
||||
sich im Kapitel <20>ber die Mustererkennung (\ref{mustererkennung}).
|
||||
|
||||
Die folgenden Mechanismen stehen in der Standard-Shell bereit, um mit Variablen zu hantieren. Bei allen Angaben ist der Doppelpunkt optional. Wenn er aber angegeben wird, mu<6D> die \textsl{Variable} einen Wert enthalten. \nopagebreak
|
||||
\LTXtable{\textwidth}{tab_variablen_substitution.tex}
|
||||
@ -100,7 +128,11 @@ Die folgenden Mechanismen stehen in der Standard-Shell bereit, um mit Variablen
|
||||
|
||||
\index{' '=\texttt{' '}|see{Ticks}}\index{` `=\texttt{` `}|see{Backticks}}\index{\dq~\dq=\texttt{\dq~\dq}|see{Anf<EFBFBD>hrungszeichen}}\index{\textbackslash=\texttt{\textbackslash}|see{Backslash}}
|
||||
|
||||
Dies ist ein sehr schwieriges Thema, da hier mehrere <20>hnlich aussehende Zeichen v<>llig verschiedene Effekte bewirken. Unix unterscheidet allein zwischen drei verschiedenen Anf<6E>hrungszeichen. Das Quoten dient dazu, bestimmte Zeichen mit einer Sonderbedeutung vor der Shell zu `verstecken' um zu verhindern, da<64> diese expandiert (ersetzt) werden.
|
||||
Dies ist ein sehr schwieriges Thema, da hier mehrere <20>hnlich aussehende Zeichen
|
||||
v<EFBFBD>llig verschiedene Effekte bewirken. Die Bourne-Shell unterscheidet allein
|
||||
zwischen drei verschiedenen Anf<6E>hrungszeichen. Das Quoten dient dazu, bestimmte
|
||||
Zeichen mit einer Sonderbedeutung vor der Shell zu `verstecken' um zu
|
||||
verhindern, da<64> diese expandiert (ersetzt) werden.
|
||||
|
||||
Die folgenden Zeichen haben eine spezielle Bedeutung innerhalb der Shell:\nopagebreak
|
||||
\LTXtable{\textwidth}{tab_quoting_sonderzeichen.tex}
|
||||
@ -123,8 +155,16 @@ Bei der Angabe von Dateinamen k
|
||||
Die wichtigsten Meta-Zeichen sind:\nopagebreak
|
||||
\LTXtable{\textwidth}{tab_metazeichen.tex}
|
||||
|
||||
\texttt{\~}, \texttt{\~{}}\textsl{name}, \texttt{\~{}+} und \texttt{\~{}-}
|
||||
werden nicht von jeder Shell unterst<73>tzt.
|
||||
|
||||
\medskip\emph{Beispiele:}\nopagebreak
|
||||
\LTXtable{\textwidth}{tab_beisp_metazeichen.tex}
|
||||
|
||||
Hier ist anzumerken, da<64> Hidden Files (Dateien, deren Name mit einem Punkt
|
||||
beginnt) nicht durch ein einfaches \texttt{*} erfa<66>t werden, sondern nur durch
|
||||
das Suchmuster \texttt{.*}.
|
||||
|
||||
\index{*=\texttt{*}|)}\index{?=\texttt{?}|)}\index{[abc]=\texttt{[}\textsl{abc}\texttt{]}|)}\index{[a-q]=\texttt{[}\textsl{a}\texttt{-}\textsl{q}\texttt{]}|)}\index{[!!abc]=\texttt{[!!}\textsl{abc}\texttt{]}|)}\index{Dateinamen|)}
|
||||
\index{\~{}=\texttt{\~{}}|)}\index{\~{}name=\texttt{\~{}}\textsl{name}|)}\index{\~{}+=\texttt{\~{}+}|)}\index{\~{}-=\texttt{\~{}-}|)}
|
||||
\index{Meta-Zeichen|)}
|
||||
@ -145,10 +185,11 @@ TODO!!!
|
||||
|
||||
Man unterscheidet in der Shell-Programmierung zwischen den
|
||||
Meta-Zeichen\index{Meta-Zeichen}, die bei der Bezeichnung von Dateinamen
|
||||
eingesetzt werden (sogenanntes `Globbing'\index{Globbing}) und den Meta-Zeichen, die in
|
||||
mehreren Programmen Verwendung finden, um z. B. Suchmuster zu definieren. Diese
|
||||
Muster werden auch regul<75>re Ausdr<64>cke (regular expression)\index{Regular
|
||||
Expression|see{Regul<EFBFBD>rer Ausdruck}}\index{Expression|see{Regul<EFBFBD>rer
|
||||
eingesetzt werden (sogenanntes `Globbing'\index{Globbing}) und den
|
||||
Meta-Zeichen, die in mehreren Programmen Verwendung finden, um z. B. Suchmuster
|
||||
zu definieren. Diese Muster werden auch regul<75>re Ausdr<64>cke (regular
|
||||
expression)\index{Regular Expression|see{Regul<EFBFBD>rer
|
||||
Ausdruck}}\index{Expression|see{Regul<EFBFBD>rer
|
||||
Ausdruck}}\index{Ausdruck|see{Regul<EFBFBD>rer Ausdruck}} genannt. Sie bieten
|
||||
wesentlich mehr M<>glichkeiten als die relativ einfachen Wildcards f<>r
|
||||
Dateinamen.
|
||||
@ -198,9 +239,20 @@ Kommentare in der Shell beginnen immer mit dem Nummern-Zeichen (\verb\#\). Dabei
|
||||
|
||||
\subsection{Auswahl der Shell (\texttt{\#!})}\label{auswahl_der_shell}\index{\#!!=\texttt{\#!!}|see{Shell / Auswahl der\ldots}}\index{Shell>Auswahl der\ldots|(textbf}
|
||||
|
||||
In der ersten Zeile eines Shell-Skriptes sollte definiert werden, mit welcher Shell das Skript ausgef<65>hrt werden soll. Das System <20>ffnet dann eine Subshell\index{Subshell} und f<>hrt das restliche Skript in dieser aus.
|
||||
In der ersten Zeile eines Shell-Skriptes sollte definiert werden, mit welchem
|
||||
Programm das Skript ausgef<65>hrt werden soll. Das System <20>ffnet dann eine
|
||||
Subshell\index{Subshell} und f<>hrt das restliche Skript in dieser aus.
|
||||
|
||||
Die Angabe erfolgt <20>ber eine Zeile in der Form \verb\#!/bin/sh\, wobei unter
|
||||
\verb\/bin/sh\ die entsprechende Shell (in diesem Fall die Bourne-Shell) liegt.
|
||||
Dieser Eintrag wirkt nur dann, wenn er in der ersten Zeile und der ersten
|
||||
Spalte des Skripts steht.
|
||||
|
||||
Dieser Mechanismus ist bei der Bourne-Shell nicht vorhanden, er wurde mit den
|
||||
moderneren Shells eingef<65>hrt um eben durch die Angabe von \verb\#!/bin/sh\ die
|
||||
Bourne-Shell f<>r die Ausf<73>hrung von Shell-Skripten benutzen zu k<>nnen. In der
|
||||
Bourne-Shell wirkt das f<>hrende \verb\#\ als Kommentarzeichen.
|
||||
|
||||
Die Angabe erfolgt <20>ber eine Zeile in der Form \verb\#!/bin/sh\, wobei unter \verb\/bin/sh\ die entsprechende Shell (in diesem Fall die Bourne-Shell) liegt. Dieser Eintrag wirkt nur dann, wenn er in der ersten Zeile des Skripts steht.
|
||||
\index{Shell>Auswahl der\ldots|)}
|
||||
|
||||
|
||||
@ -223,13 +275,17 @@ Die `gesourcte' Datei wird eingelesen und ausgef
|
||||
\index{source=\texttt{source}|)}
|
||||
|
||||
|
||||
\subsection{Funktionen}\index{Funktion|(textbf}
|
||||
\subsection{Funktionen}\label{funktionen}\index{Funktion|(textbf}
|
||||
|
||||
Es ist in der Shell auch m<>glich, <20>hnlich wie in einer `richtigen' Programmiersprache Funktionen zu deklarieren und zu benutzen. Da die Bourne-Shell (\verb\sh\) nicht <20>ber Aliase\index{Aliase} verf<72>gt, k<>nnen einfache Funktionen als Ersatz dienen.
|
||||
|
||||
Der R<>ckgabewert einer Funktion ist gleich dem R<>ckgabewert des letzten in der Funktion aufgerufenen Kommandos.
|
||||
Der R<>ckgabewert einer Funktion ist gleich dem R<>ckgabewert des letzten in der
|
||||
Funktion aufgerufenen Kommandos, es sei denn man gibt mittels
|
||||
\verb\return\ (Siehe \ref{return}) explizit einen anderen Wert zur<75>ck.
|
||||
|
||||
\medskip\emph{Beispiel:} Die Funktion gibt die Anzahl der Dateien im aktuellen Verzeichnis zur<75>ck. Aufgerufen wird diese Funktion wie ein Befehl, also einfach durch die Eingabe von \verb\count\.\nopagebreak
|
||||
\medskip\emph{Beispiel:} Die Funktion gibt die Anzahl der Dateien im aktuellen
|
||||
Verzeichnis aus. Aufgerufen wird diese Funktion wie ein Befehl, also einfach
|
||||
durch die Eingabe von \verb\count\.\nopagebreak
|
||||
\LTXtable{\textwidth}{tab_beisp_funktionen.tex}
|
||||
\index{Funktion|)}
|
||||
|
||||
@ -373,6 +429,17 @@ Die \texttt{exit}-Anweisung wird benutzt, um ein Skript zu beenden. Wenn der Par
|
||||
\index{exit=\texttt{exit}|)}
|
||||
|
||||
|
||||
\subsection{return}\label{return}\index{return=\texttt{return}|(textbf}
|
||||
|
||||
Die Syntax der \texttt{return}-Anweisung lautet wie folgt:\nopagebreak
|
||||
\LTXtable{\textwidth}{tab_return.tex}
|
||||
|
||||
Mittels \texttt{return} kann eine Funktion (siehe \ref{funktionen}) einen
|
||||
bestimmten Wert zur<75>ckgeben. Anderenfalls wird der Exit-Code des letzten in der
|
||||
Funktion ausgef<65>hrten Befehls zur<75>ckgegeben.
|
||||
\index{return=\texttt{return}|)}
|
||||
|
||||
|
||||
\section{Befehlsformen}\label{befehlsformen}\index{Befehls>-formen|(textbf}
|
||||
\index{\&=\texttt{\&}|(textbf}\index{;=\texttt{;}|(textbf}\index{( )=\texttt{( )}|(textbf}\index{\{ \}=\texttt{\{ \}}|(textbf}\index{Pipe|(textbf}\index{Backticks|(textbf}\index{\&\&=\texttt{\&\&}|(textbf}\index{!|!|=\texttt{!|!|}|(textbf}\index{Befehls>-substitution|(textbf}\index{Befehls>-folge|(textbf}\index{Befehls>-block|(textbf}
|
||||
\index{!|=\texttt{!|}|see{Pipe}}\index{Substitution|see{Befehls-Subst.}}
|
||||
|
Reference in New Issue
Block a user