Viele Aenderungen

This commit is contained in:
rschaten
2005-01-21 17:23:30 +00:00
parent 52635f366a
commit 68d30297e6
6 changed files with 209 additions and 84 deletions

View File

@@ -16,10 +16,10 @@ Einfacher geht es, wenn wir uns ein kurzes Skript schreiben, das alle 30 Sekunde
\index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{Pipe}\index{grep=\texttt{grep}}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}}
\begin{lstlisting}
#!/bin/sh
until who | grep "^root "
do sleep 30
until who | grep "^root "; do
sleep 30
done
echo Big Brother is watching you!
echo "Big Brother is watching you!"
\end{lstlisting}
Das Skript f<>hrt also so lange das Kommando aus, bis die Ausf<73>hrung erfolgreich
@@ -42,10 +42,10 @@ Analog zum vorhergehenden Beispiel kann man auch ein Skript schreiben, das melde
\index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{grep=\texttt{grep}}\index{Pipe}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}}
\begin{lstlisting}
#!/bin/sh
while who | grep "^root "
do sleep 30
while who | grep "^root "; do
sleep 30
done
echo Die Katze ist aus dem Haus, Zeit, da<64> die M<>use tanzen!
echo "Die Katze ist aus dem Haus, Zeit, da<64> die M<>use tanzen!"
\end{lstlisting}
Die Schleife wird n<>mlich dann so lange ausgef<65>hrt, bis \texttt{grep}\index{grep=\texttt{grep}} einen Fehler (bzw. eine erfolglose Suche) zur<75>ckmeldet.
@@ -245,18 +245,31 @@ echo "aflag=$aflag / Name = $name / Die Dateien sind $*"
\end{lstlisting}
\section{Fallensteller: Auf Traps
reagieren}\label{traps}\index{trap=\texttt{trap}|(}\index{Signal|(}
\section{Fallensteller: Auf Traps reagieren}\label{traps}\index{trap=\texttt{trap}|(}\index{Signal|(}
Ein laufendes Shell-Skript kann durch Druck auf die Interrupt-Taste (normalerweise \Ovalbox{CTRL}-\Ovalbox{C}) unterbrochen werden. Durch Druck auf diese Taste wird ein Signal an den entsprechenden Proze<7A> gesandt, das ihn bittet sich zu beenden. Dieses Signal hei<65>t SIGINT (f<>r SIGnal INTerrupt) und tr<74>gt die Nummer 2. Das kann ein kleines Problem darstellen, wenn das Skript sich tempor<6F>re Dateien angelegt hat, da diese nach der Ausf<73>hrung nur noch unn<6E>tig Platz verbrauchen und eigentlich gel<65>scht werden sollten. Man kann sich sicher auch noch wichtigere F<>lle vorstellen, in denen ein Skript bestimmte Aufgaben auf jeden Fall erledigen mu<6D>, bevor es sich beendet.
Ein laufendes Shell-Skript kann durch Druck auf die Interrupt-Taste
(normalerweise \Ovalbox{CTRL}-\Ovalbox{C}) unterbrochen werden. Durch Druck auf
diese Taste wird ein Signal an den entsprechenden Proze<7A> gesandt, das ihn
bittet sich zu beenden. Dieses Signal hei<65>t SIGINT (f<>r SIGnal INTerrupt) und
tr<EFBFBD>gt die Nummer 2. Das kann ein kleines Problem darstellen, wenn das Skript
sich tempor<6F>re Dateien angelegt hat, da diese nach der Ausf<73>hrung nur noch
unn<EFBFBD>tig Platz verbrauchen und eigentlich gel<65>scht werden sollten. Man kann
sich sicher auch noch wichtigere F<>lle vorstellen, in denen ein Skript
bestimmte Aufgaben auf jeden Fall erledigen mu<6D>, bevor es sich beendet.
Es gibt eine Reihe weiterer Signale, auf die ein Skript reagieren kann. Alle sind in der Man-Page von \texttt{signal} beschrieben. Hier die wichtigsten:\nopagebreak
Es gibt eine Reihe weiterer Signale, auf die ein Skript reagieren kann. Alle
sind in der Man-Page von \texttt{signal} beschrieben. Hier die
wichtigsten:\nopagebreak
\LTXtable{\textwidth}{tab_signale.tex}
Wie l<>st man jetzt dieses Problem? Gl<47>cklicherweise verf<72>gt die Shell <20>ber das \texttt{trap}-Kommando, mit dessen Hilfe man auf diese Signale reagieren kann. Die Anwendung soll in folgendem Skript beispielhaft dargestellt werden.
Wie l<>st man jetzt dieses Problem? Gl<47>cklicherweise verf<72>gt die Shell <20>ber das
\texttt{trap}-Kommando, mit dessen Hilfe man auf diese Signale reagieren kann.
Die Anwendung soll in folgendem Skript beispielhaft dargestellt werden.
Das Skript soll eine komprimierte Textdatei mittels \texttt{zcat} in ein tempor<6F>res File entpacken, dieses mit \texttt{pg} seitenweise anzeigen und nachher wieder l<>schen.
Das Skript soll eine komprimierte Textdatei mittels \texttt{zcat} in ein
tempor<EFBFBD>res File entpacken, dieses mit \texttt{pg} seitenweise anzeigen und
nachher wieder l<>schen.
\index{!==\texttt{!=}}
\begin{lstlisting}
@@ -266,7 +279,12 @@ temp=/tmp/zeige$$
\end{lstlisting}
Zun<EFBFBD>chst werden zwei Variablen belegt, die im weiteren Verlauf benutzt werden sollen. In \texttt{stat} wird der Wert abgelegt, den das Skript im Falle eines Abbruchs als Exit-Status zur<75>ckliefern soll. Die Variable \texttt{temp} enth<74>lt den Namen f<>r eine tempor<6F>re Datei. Dieser setzt sich zusammen aus \texttt{/tmp/zeige} und der Proze<7A>nummer des laufenden Skripts. So soll sichergestellt werden, da<64> noch keine Datei mit diesem Namen existiert.
Zun<EFBFBD>chst werden zwei Variablen belegt, die im weiteren Verlauf benutzt werden
sollen. In \texttt{stat} wird der Wert abgelegt, den das Skript im Falle eines
Abbruchs als Exit-Status zur<75>ckliefern soll. Die Variable \texttt{temp} enth<74>lt
den Namen f<>r eine tempor<6F>re Datei. Dieser setzt sich zusammen aus
\texttt{/tmp/zeige} und der Proze<7A>nummer des laufenden Skripts. So soll
sichergestellt werden, da<64> noch keine Datei mit diesem Namen existiert.
\index{Ticks}\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Ticks}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
\begin{lstlisting}[firstnumber=last]
@@ -275,7 +293,17 @@ trap 'echo "`basename $0`: Ooops..." 1>&2' 1 2 15
\end{lstlisting}
Hier werden die Traps definiert. Bei Signal 0 wird die tempor<6F>re Datei gel<65>scht und der Wert aus der Variable \texttt{stat} als Exit-Code zur<75>ckgegeben. Dabei wird dem \texttt{rm}-Kommando der Parameter\index{Parameter} \texttt{-f} mitgegeben, damit keine Fehlermeldung ausgegeben wird, falls die Datei (noch) nicht existiert. Dieser Fall tritt bei jedem Beenden des Skriptes auf, also sowohl bei einem normalen Ende, als auch beim Exit-Kommando, bei einem Interrupt oder bei einem Kill\index{kill=\texttt{kill}}. Der zweite Trap reagiert auf die Signale 1, 2 und 15. Das hei<65>t, er wird bei jedem unnormalen Ende ausgef<65>hrt. Er gibt eine entsprechende Meldung auf die Standard-Fehlerausgabe (\ref{datenstrom}) aus. Danach wird das Skript beendet, und der erste Trap wird ausgef<65>hrt.
Hier werden die Traps definiert. Bei Signal 0 wird die tempor<6F>re Datei gel<65>scht
und der Wert aus der Variable \texttt{stat} als Exit-Code zur<75>ckgegeben. Dabei
wird dem \texttt{rm}-Kommando der Parameter\index{Parameter} \texttt{-f}
mitgegeben, damit keine Fehlermeldung ausgegeben wird, falls die Datei (noch)
nicht existiert. Dieser Fall tritt bei jedem Beenden des Skriptes auf, also
sowohl bei einem normalen Ende, als auch beim Exit-Kommando, bei einem
Interrupt oder bei einem Kill\index{kill=\texttt{kill}}. Der zweite Trap
reagiert auf die Signale 1, 2 und 15. Das hei<65>t, er wird bei jedem unnormalen
Ende ausgef<65>hrt. Er gibt eine entsprechende Meldung auf die
Standard-Fehlerausgabe (\ref{datenstrom}) aus. Danach wird das Skript beendet,
und der erste Trap wird ausgef<65>hrt.
\index{\$\#=\texttt{\$\#}}\index{!==\texttt{!=}}\index{!>=\texttt{!>}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}}
\begin{lstlisting}[firstnumber=last]
@@ -287,7 +315,14 @@ case $# in
\end{lstlisting}
Jetzt kommt die eigentliche Funktionalit<69>t des Skriptes: Das \texttt{case}-Kommando (\ref{case}) testet die Anzahl der <20>bergebenen Parameter\index{Parameter}. Wenn genau ein Parameter\index{Parameter} <20>bergeben wurde, entpackt \texttt{zcat} die Datei, die im ersten Parameter\index{Parameter} angegeben wurde, in die tempor<6F>re Datei. Dann folgt die Seitenweise Ausgabe mittels \texttt{pg}. Nach Beendigung der Ausgabe wird der Status in der Variablen auf 0 gesetzt, damit beim Skriptende der korrekte Exit-Code zur<75>ckgegeben wird.
Jetzt kommt die eigentliche Funktionalit<69>t des Skriptes: Das
\texttt{case}-Kommando (\ref{case}) testet die Anzahl der <20>bergebenen
Parameter\index{Parameter}. Wenn genau ein Parameter\index{Parameter} <20>bergeben
wurde, entpackt \texttt{zcat} die Datei, die im ersten
Parameter\index{Parameter} angegeben wurde, in die tempor<6F>re Datei. Dann folgt
die Seitenweise Ausgabe mittels \texttt{pg}. Nach Beendigung der Ausgabe wird
der Status in der Variablen auf 0 gesetzt, damit beim Skriptende der korrekte
Exit-Code zur<75>ckgegeben wird.
\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
\begin{lstlisting}[firstnumber=last]
@@ -296,7 +331,9 @@ esac
\end{lstlisting}
Wenn \texttt{case} eine andere Parameterzahl feststellt, wird eine Meldung mit der Aufrufsyntax auf die Standard-Fehlerausgabe geschrieben.
Wenn \texttt{case} eine andere Parameterzahl feststellt, wird eine Meldung mit
der Aufrufsyntax auf die Standard-Fehlerausgabe geschrieben.
\index{trap=\texttt{trap}|)}\index{Signal|)}