Viele Aenderungen
This commit is contained in:
@@ -16,10 +16,10 @@ Einfacher geht es, wenn wir uns ein kurzes Skript schreiben, das alle 30 Sekunde
|
||||
\index{\^=\texttt{\^}}\index{Anfü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ührung erfolgreich
|
||||
@@ -42,10 +42,10 @@ Analog zum vorhergehenden Beispiel kann man auch ein Skript schreiben, das melde
|
||||
\index{\^=\texttt{\^}}\index{Anfü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ß die Mäuse tanzen!
|
||||
echo "Die Katze ist aus dem Haus, Zeit, daß die Mäuse tanzen!"
|
||||
\end{lstlisting}
|
||||
|
||||
Die Schleife wird nämlich dann so lange ausgeführt, bis \texttt{grep}\index{grep=\texttt{grep}} einen Fehler (bzw. eine erfolglose Suche) zurü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ß gesandt, das ihn bittet sich zu beenden. Dieses Signal heißt SIGINT (für SIGnal INTerrupt) und trägt die Nummer 2. Das kann ein kleines Problem darstellen, wenn das Skript sich temporäre Dateien angelegt hat, da diese nach der Ausführung nur noch unnötig Platz verbrauchen und eigentlich gelöscht werden sollten. Man kann sich sicher auch noch wichtigere Fälle vorstellen, in denen ein Skript bestimmte Aufgaben auf jeden Fall erledigen muß, 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ß gesandt, das ihn
|
||||
bittet sich zu beenden. Dieses Signal heißt SIGINT (für SIGnal INTerrupt) und
|
||||
trägt die Nummer 2. Das kann ein kleines Problem darstellen, wenn das Skript
|
||||
sich temporäre Dateien angelegt hat, da diese nach der Ausführung nur noch
|
||||
unnötig Platz verbrauchen und eigentlich gelöscht werden sollten. Man kann
|
||||
sich sicher auch noch wichtigere Fälle vorstellen, in denen ein Skript
|
||||
bestimmte Aufgaben auf jeden Fall erledigen muß, 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ücklicherweise verfügt die Shell ü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ücklicherweise verfügt die Shell ü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ä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ä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ä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ückliefern soll. Die Variable \texttt{temp} enthält den Namen für eine temporäre Datei. Dieser setzt sich zusammen aus \texttt{/tmp/zeige} und der Prozeßnummer des laufenden Skripts. So soll sichergestellt werden, daß noch keine Datei mit diesem Namen existiert.
|
||||
Zunä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ückliefern soll. Die Variable \texttt{temp} enthält
|
||||
den Namen für eine temporäre Datei. Dieser setzt sich zusammen aus
|
||||
\texttt{/tmp/zeige} und der Prozeßnummer des laufenden Skripts. So soll
|
||||
sichergestellt werden, daß noch keine Datei mit diesem Namen existiert.
|
||||
|
||||
\index{Ticks}\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Ticks}\index{Anfü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äre Datei gelöscht und der Wert aus der Variable \texttt{stat} als Exit-Code zurü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ßt, er wird bei jedem unnormalen Ende ausgeführt. Er gibt eine entsprechende Meldung auf die Standard-Fehlerausgabe (\ref{datenstrom}) aus. Danach wird das Skript beendet, und der erste Trap wird ausgeführt.
|
||||
Hier werden die Traps definiert. Bei Signal 0 wird die temporäre Datei gelöscht
|
||||
und der Wert aus der Variable \texttt{stat} als Exit-Code zurü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ßt, er wird bei jedem unnormalen
|
||||
Ende ausgeführt. Er gibt eine entsprechende Meldung auf die
|
||||
Standard-Fehlerausgabe (\ref{datenstrom}) aus. Danach wird das Skript beendet,
|
||||
und der erste Trap wird ausgeführt.
|
||||
|
||||
\index{\$\#=\texttt{\$\#}}\index{!==\texttt{!=}}\index{!>=\texttt{!>}}\index{\$n=\texttt{\$}$n$}\index{Anführungszeichen}\index{case=\texttt{case}}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
@@ -287,7 +315,14 @@ case $# in
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Jetzt kommt die eigentliche Funktionalität des Skriptes: Das \texttt{case}-Kommando (\ref{case}) testet die Anzahl der übergebenen Parameter\index{Parameter}. Wenn genau ein Parameter\index{Parameter} übergeben wurde, entpackt \texttt{zcat} die Datei, die im ersten Parameter\index{Parameter} angegeben wurde, in die temporä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ückgegeben wird.
|
||||
Jetzt kommt die eigentliche Funktionalität des Skriptes: Das
|
||||
\texttt{case}-Kommando (\ref{case}) testet die Anzahl der übergebenen
|
||||
Parameter\index{Parameter}. Wenn genau ein Parameter\index{Parameter} übergeben
|
||||
wurde, entpackt \texttt{zcat} die Datei, die im ersten
|
||||
Parameter\index{Parameter} angegeben wurde, in die temporä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ückgegeben wird.
|
||||
|
||||
\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Anfü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|)}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user