Umformatiert
This commit is contained in:
310
beispiele.tex
310
beispiele.tex
@ -13,34 +13,40 @@ Angenommen, bei der Benutzung eines Rechners tritt ein Problem auf, bei dem nur
|
||||
|
||||
Einfacher geht es, wenn wir uns ein kurzes Skript schreiben, das alle 30 Sekunden automatisch <20>berpr<70>ft, ob der Admin angemeldet ist. Wir erreichen das mit dem folgenden Code:
|
||||
|
||||
\footnotesize
|
||||
\index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{Pipe}\index{grep=\texttt{grep}}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}}
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
until who | grep "^root "
|
||||
do sleep 30
|
||||
done
|
||||
echo Big Brother is watching you!
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
Das Skript f<>hrt also so lange das Kommando aus, bis die Ausf<73>hrung erfolgreich war. Dabei wird die Ausgabe von \texttt{who}\index{who=\texttt{who}} mit einer Pipe (\ref{datenstrom}) in das \texttt{grep}\index{grep=\texttt{grep}}-Kommando umgeleitet. Dieses sucht darin nach einem Auftreten von `\texttt{root~}' am Zeilenanfang. Der R<>ckgabewert von \texttt{grep}\index{grep=\texttt{grep}} ist 0 wenn das Muster\index{Mustererkennung} gefunden wird, 1 wenn es nicht gefunden wird und 2 wenn ein Fehler auftrat. Damit der Rechner nicht die ganze Zeit mit dieser Schleife besch<63>ftigt ist, wird im Schleifenk<6E>rper ein \texttt{sleep 30}\index{sleep=\texttt{sleep}} ausgef<65>hrt, um den Proze<7A> f<>r 30 Sekunden schlafen zu schicken. Sobald der Admin sich eingeloggt hat, wird eine entsprechende Meldung ausgegeben.
|
||||
Das Skript f<>hrt also so lange das Kommando aus, bis die Ausf<73>hrung erfolgreich
|
||||
war. Dabei wird die Ausgabe von \texttt{who}\index{who=\texttt{who}} mit einer
|
||||
Pipe (\ref{datenstrom}) in das \texttt{grep}\index{grep=\texttt{grep}}-Kommando
|
||||
umgeleitet. Dieses sucht darin nach einem Auftreten von `\texttt{root~}' am
|
||||
Zeilenanfang. Der R<>ckgabewert von \texttt{grep}\index{grep=\texttt{grep}} ist
|
||||
0 wenn das Muster\index{Mustererkennung} gefunden wird, 1 wenn es nicht
|
||||
gefunden wird und 2 wenn ein Fehler auftrat. Damit der Rechner nicht die ganze
|
||||
Zeit mit dieser Schleife besch<63>ftigt ist, wird im Schleifenk<6E>rper ein
|
||||
\lstinline|sleep 30|\index{sleep=\texttt{sleep}} ausgef<65>hrt, um den Proze<7A> f<>r
|
||||
30 Sekunden schlafen zu schicken. Sobald der Admin sich eingeloggt hat, wird
|
||||
eine entsprechende Meldung ausgegeben.
|
||||
|
||||
|
||||
\subsection{Schleife, bis ein Kommando erfolglos war}
|
||||
|
||||
Analog zum vorhergehenden Beispiel kann man auch ein Skript schreiben, das meldet, sobald sich ein Benutzer abgemeldet hat. Dazu ersetzen wir nur die \texttt{until}- Schleife durch eine entsprechende \texttt{while}-Schleife:
|
||||
|
||||
\footnotesize
|
||||
\index{\^=\texttt{\^}}\index{Anf<EFBFBD>hrungszeichen}\index{grep=\texttt{grep}}\index{Pipe}\index{sleep=\texttt{sleep}}\index{who=\texttt{who}}
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
while who | grep "^root "
|
||||
do sleep 30
|
||||
done
|
||||
echo Die Katze ist aus dem Haus, Zeit, da<64> die M<>use tanzen!
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\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.
|
||||
|
||||
@ -49,8 +55,7 @@ Die Schleife wird n
|
||||
|
||||
\texttt{cat datei.txt | while read i}
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
count=0
|
||||
cat /etc/passwd | while read i; do
|
||||
@ -61,8 +66,7 @@ cat /etc/passwd | while read i; do
|
||||
fi
|
||||
done
|
||||
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
TODO!!! Daten aus Subshell hochreichen
|
||||
|
||||
@ -76,19 +80,16 @@ Das Skript mu
|
||||
|
||||
Das Ergebnis der Ausf<73>hrung wird mit Funktionen\index{Funktion} dargestellt, die aus der Datei \texttt{/etc/rc.d/init.d/functions} stammen. Ebenfalls in dieser Datei sind Funktionen, die einen Dienst starten oder stoppen.
|
||||
|
||||
\begin{flushright}
|
||||
Zun<EFBFBD>chst wird festgelegt, da<64> dieses Skript in der Bourne-Shell ausgef<65>hrt werden soll (\ref{auswahl_der_shell}).
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Dann folgen Kommentare\index{Kommentar}, die den Sinn des Skriptes erl<72>utern (\ref{kommentare}).
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
\begin{listingcont}
|
||||
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
#
|
||||
# Startup script for the Apache Web Server
|
||||
#
|
||||
@ -100,119 +101,109 @@ Dann folgen Kommentare\index{Kommentar}, die den Sinn des Skriptes erl
|
||||
# config: /etc/httpd/conf/access.conf
|
||||
# config: /etc/httpd/conf/httpd.conf
|
||||
# config: /etc/httpd/conf/srm.conf
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Jetzt wird die Datei mit den Funktionen\index{Funktion} eingebunden (\ref{source}).
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{source=\texttt{source}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Hier werden die Aufrufparameter ausgewertet (\ref{case}).
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting httpd: "
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Nachdem eine Meldung <20>ber den auszuf<75>hrenden Vorgang ausgegeben wurde, wird die Funktion \texttt{daemon} aus der Funktionsbibliothek ausgef<65>hrt. Diese Funktion startet das Programm, dessen Name hier als Parameter\index{Parameter} <20>bergeben wird. Dann gibt sie eine Meldung <20>ber den Erfolg aus.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
\begin{listingcont}
|
||||
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
daemon httpd
|
||||
echo
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Jetzt wird ein Lock-File\footnote{Ein Lock-File signalisiert anderen Prozessen, da<64> ein bestimmter Proze<7A> bereits gestartet ist. So kann ein zweiter Aufruf verhindert werden.} angelegt.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{Anf<EFBFBD>hrungszeichen}\index{touch=\texttt{touch}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
touch /var/lock/subsys/httpd
|
||||
;;
|
||||
stop)
|
||||
echo -n "Shutting down http: "
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Hier passiert im Prinzip das gleiche wie oben, nur da<64> mit der Funktion \texttt{killproc} der Daemon angehalten wird.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
\begin{listingcont}
|
||||
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
killproc httpd
|
||||
echo
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Danach werden Lock-File und PID-File\footnote{In einem sogenannten PID-File hinterlegen einige Prozesse ihre Proze<7A>-ID, um anderen Programmen den Zugriff zu erleichtern (z. B. um den Proze<7A> anzuhalten etc).} gel<65>scht.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
\begin{listingcont}
|
||||
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
rm -f /var/lock/subsys/httpd
|
||||
rm -f /var/run/httpd.pid
|
||||
;;
|
||||
status)
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Die Funktion \texttt{status} stellt fest, ob der entsprechende Daemon bereits l<>uft, und gibt das Ergebnis aus.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
\begin{listingcont}
|
||||
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
status httpd
|
||||
;;
|
||||
restart)
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Bei Aufruf mit dem Parameter\index{Parameter} \textsl{restart} ruft sich das Skript zwei mal selbst auf (in \texttt{\$0} steht der Aufrufname des laufenden Programms). Einmal, um den Daemon zu stoppen, dann, um ihn wieder zu starten.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
reload)
|
||||
echo -n "Reloading httpd: "
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Hier sendet die \texttt{killproc}-Funktion dem Daemon ein Signal\index{Signal} das ihm sagt, da<64> er seine Konfiguration neu einlesen soll.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
killproc httpd -HUP
|
||||
echo
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|reload|status}"
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Bei aufruf mit einem beliebigen anderen Parameter\index{Parameter} wird eine Kurzhilfe ausgegeben. Dann wird daf<61>r gesorgt, da<64> das Skript mit dem Exit-Code 1 beendet wird. So kann festgestellt werden, ob das Skript ordnungsgem<65><6D> beendet wurde (\ref{exit}).
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{exit=\texttt{exit}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit 0
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\section{Parameter<EFBFBD>bergabe in der Praxis}\label{beisp_parameter}\index{Parameter}
|
||||
@ -221,21 +212,19 @@ Es kommt in der Praxis sehr oft vor, da
|
||||
|
||||
Das soll an folgendem Skript verdeutlicht werden. Das Skript kennt die Optionen \texttt{-a} und \texttt{-b}. Letzterer Option mu<6D> ein zus<75>tzlicher Wert mitgegeben werden. Alle anderen Parameter\index{Parameter} werden als Dateinamen interpretiert.
|
||||
|
||||
\footnotesize
|
||||
\index{\$@=\texttt{\$@}}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{!|!|=\texttt{!|!|}}\index{getopt=\texttt{getopt}}\index{OR}\index{set=\texttt{set}}
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
set -- `getopt "ab:" "$@"` || {
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Das \texttt{set}\index{set=\texttt{set}}-Kommando belegt den Inhalt der vordefinierten Variablen (\ref{vordefinierte_variablen}) neu, so da<64> es aussieht, als ob dem Skript die R<>ckgabewerte von \texttt{getopt}\index{getopt=\texttt{getopt}} <20>bergeben wurden. Man mu<6D> die beiden Minuszeichen angeben, da sie daf<61>r sorgen, da<64> die Aufrufparameter an \texttt{getopt}\index{getopt=\texttt{getopt}} und nicht an die Shell selbst <20>bergeben werden. Die originalen Parameter\index{Parameter} werden von \texttt{getopt}\index{getopt=\texttt{getopt}} untersucht und modifiziert zur<75>ckgegeben: \texttt{a} und \texttt{b} werden als Parameter\index{Parameter} Markiert, \texttt{b} sogar mit der M<>glichkeit einer zus<75>tzlichen Angabe.
|
||||
|
||||
Wenn dieses Kommando fehlschl<68>gt ist das ein Zeichen daf<61>r, da<64> falsche Parameter\index{Parameter} <20>bergeben wurden. Also wird nach einer entsprechenden Meldung das Programm mit Exit-Code 1 verlassen.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{\$n=\texttt{\$}$n$}\index{Null-Befehl}\index{!>\&=\texttt{!>\&}}\index{!==\texttt{!=}}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
echo "Anwendung: `basename $0` [-a] [-b Name] Dateien" 1>&2
|
||||
exit 1
|
||||
}
|
||||
@ -243,41 +232,38 @@ echo "Momentan steht in der Kommandozeile folgendes: $*"
|
||||
aflag=0 name=NONE
|
||||
while :
|
||||
do
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
In einer Endlosschleife\index{Endlosschleife}, die man mit Hilfe des Null-Befehls (\texttt{:}, \ref{null-befehl}) baut, werden die `neuen' Parameter\index{Parameter} der Reihe nach untersucht. Wenn ein \texttt{-a} vorkommt, wird die Variable \texttt{aflag} gesetzt. Bei einem \texttt{-b} werden per \texttt{shift}\index{shift=\texttt{shift}} alle Parameter\index{Parameter} nach Links verschoben, dann wird der Inhalt des n<>chsten Parameters\index{Parameter} in der Variablen \texttt{name} gesichert.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{!==\texttt{!=}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}}\index{shift=\texttt{shift}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
case "$1" in
|
||||
-a) aflag=1 ;;
|
||||
-b) shift; name="$1" ;;
|
||||
--) break ;;
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Wenn ein \texttt{-{}-} erscheint, ist das ein Hinweis darauf, da<64> die Liste der Parameter\index{Parameter} abgearbeitet ist. Dann wird per \texttt{break}\index{break=\texttt{break}} (\ref{break}) die Endlosschleife unterbrochen. Die Aufrufparameter enthalten jetzt nur noch die eventuell angegebenen Dateinamen, die jetzt von dem Restlichen Skript wie gewohnt weiterverarbeitet werden k<>nnen.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{shift=\texttt{shift}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
esac
|
||||
shift
|
||||
done
|
||||
shift
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Am Ende werden die Feststellungen ausgegeben.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{\$*=\texttt{\$*}}\index{Anf<EFBFBD>hrungszeichen}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
echo "aflag=$aflag / Name = $name / Die Dateien sind $*"
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\section{Fallensteller: Auf Traps
|
||||
@ -293,50 +279,45 @@ Wie l
|
||||
|
||||
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.
|
||||
|
||||
\footnotesize
|
||||
\index{!==\texttt{!=}}
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
stat=1
|
||||
temp=/tmp/zeige$$
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\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.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{Ticks}\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Ticks}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
trap 'rm -f $temp; exit $stat' 0
|
||||
trap 'echo "`basename $0`: Ooops..." 1>&2' 1 2 15
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\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.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{\$\#=\texttt{\$\#}}\index{!==\texttt{!=}}\index{!>=\texttt{!>}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{case=\texttt{case}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
case $# in
|
||||
1) zcat "$1" > $temp
|
||||
pg $temp
|
||||
stat=0
|
||||
;;
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\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.
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{!>\&=\texttt{!>\&}}\index{\$n=\texttt{\$}$n$}\index{Anf<EFBFBD>hrungszeichen}\index{Backticks}\index{basename=\texttt{basename}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
*) echo "Anwendung: `basename $0` Dateiname" 1>&2
|
||||
esac
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Wenn \texttt{case} eine andere Parameterzahl feststellt, wird eine Meldung mit der Aufrufsyntax auf die Standard-Fehlerausgabe geschrieben.
|
||||
\end{flushright}
|
||||
\index{trap=\texttt{trap}|)}\index{Signal|)}
|
||||
|
||||
|
||||
@ -358,27 +339,25 @@ Zwecke noch etwas `bereinigt' werden.
|
||||
|
||||
Wie das aussieht, wenn es fertig ist, sieht man im folgenden Skript:
|
||||
|
||||
\footnotesize
|
||||
\index{!==\texttt{!=}}
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
for i in `find $1 -type f -name "*.[mM][pP]3"`; do
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Hier beginnt eine Schleife, die <20>ber alle Ausgaben des \texttt{find}-Kommandos
|
||||
iteriert. Dabei sucht \texttt{find} nach allen normalen Dateien (\texttt{-type
|
||||
f}), die die Extension .mp3 tragen (\texttt{-name \dq*.[mM][pP]3\dq} -- wir
|
||||
ignorieren Gro<72>- / Kleinschreibung).
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{find=\texttt{find}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
echo `tr -dc "[:alpha:]" < /dev/urandom | \
|
||||
dd count=8 bs=1 2> /dev/null`$i
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Hier ist der `magische Teil'. Mit dem \texttt{echo} wird die Ausgabe einer Pipe
|
||||
ausgegeben, gefolgt von dem aktuellen Dateinamen. Diese Pipe enth<74>lt ein
|
||||
\texttt{tr}, der alle ungewollten Zeichen (alles, was kein Textzeichen ist) aus
|
||||
@ -391,14 +370,13 @@ Kommando \texttt{dd} mit den angegebenen Parametern. Damit die Erfolgsmeldung
|
||||
von \texttt{dd} nicht die Ausgabe verunstaltet, lenken wir sie nach
|
||||
\texttt{/dev/null} um.
|
||||
\index{tr=\texttt{tr}}\index{dd=\texttt{dd}}
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{find=\texttt{find}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
done | sort | cut -b 9- | while read i; do
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
\begin{flushright}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Das Ergebnis der obigen Schleife ist also die Liste der Dateinamen, denen
|
||||
jeweils acht zuf<75>llige Zeichen vorangestellt wurden. Die Reihenfolge entspricht
|
||||
allerdings immer noch der Ausgabe von \texttt{find}, wird also nach jedem
|
||||
@ -414,15 +392,15 @@ Diese lesen wir jetzt zeilenweise mittels \texttt{read} ein. In der
|
||||
\texttt{while}-Schleife k<>nnen wir alle erforderlichen Sachen mit dem
|
||||
Dateinamen anstellen. Hier wird er nur mittels \texttt{echo} ausgegeben.
|
||||
\index{sort=\texttt{sort}}\index{cut=\texttt{cut}} \index{read=\texttt{read}}\index{while=\texttt{while}}
|
||||
\end{flushright}
|
||||
\footnotesize
|
||||
|
||||
\index{find=\texttt{find}}
|
||||
\begin{listingcont}
|
||||
\begin{lstlisting}[firstnumber=last]
|
||||
echo "Jetzt wird $i gespielt"
|
||||
mpg123 "$i"
|
||||
done
|
||||
\end{listingcont}
|
||||
\normalsize
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\index{Zufallszahlen|)}
|
||||
|
||||
|
||||
@ -437,8 +415,7 @@ das Problem, da
|
||||
Proze<EFBFBD> l<>uft oder nicht. Im Normalfall wird er zuerst folgendes ausprobieren,
|
||||
was aber oft (nicht immer) in die Hose gehen wird:
|
||||
|
||||
\texttt{ps aux | grep }\textit{prozessname}\texttt{ \&\& echo \dq}\textit{l<EFBFBD>uft
|
||||
schon}\texttt{\dq}
|
||||
\lstinline/ps aux | grep prozessname && echo "l<>uft schon"/
|
||||
|
||||
Der Grund daf<61>r ist, da<64> unter Umst<73>nden in der Ausgabe von \texttt{ps} auch
|
||||
das \texttt{grep}-Kommando samt Parameter (\textit{prozessname}) aufgelistet
|
||||
@ -447,8 +424,7 @@ wird. So findet das \texttt{grep}-Kom\-man\-do sich quasi selbst.
|
||||
Abhilfe schafft entweder \texttt{pgrep} (\ref{pgrep}) oder das folgende
|
||||
Konstrukt:
|
||||
|
||||
\texttt{ps aux | grep \dq}\textit{[p]rozessname}\texttt{\dq~\&\& echo
|
||||
\dq}\textit{l<EFBFBD>uft schon}\texttt{\dq}
|
||||
\lstinline/ps aux | grep "[p]rozessname" && echo "l<>uft schon"/
|
||||
|
||||
Das p ist jetzt als eine Zeichenmenge (regul<EFBFBD>rer Ausdruck) angegeben worden.
|
||||
Jetzt sucht \texttt{grep} also nach dem String \textit{prozessname}, in der
|
||||
@ -466,7 +442,7 @@ folgendes Szenario: Es gibt ein Verzeichnis mit vielen Unterverzeichnissen,
|
||||
denen eine Zeile mit dem Inhalt `strict' vorkommt. Man k<>nnte jetzt
|
||||
folgendes versuchen:
|
||||
|
||||
\texttt{grep -r strict *}
|
||||
\lstinline|grep -r strict *|
|
||||
|
||||
Das f<>hrt allerdings dazu, da<64> alle Dateien durchsucht werden, nicht nur die
|
||||
Perl-Skripte. Diese tragen nach unserer Konvention\footnote{Perl-Skripte m<>ssen
|
||||
@ -474,14 +450,14 @@ keine spezielle Extension haben, es sei aber um des Beispiels Willen mal
|
||||
angenommen.} die Extension `.pl'. Wir starten also eine rekursive Suche <20>ber
|
||||
alle Dateien, die dem Muster entsprechen:
|
||||
|
||||
\texttt{grep -r strict *.pl}
|
||||
\lstinline|grep -r strict *.pl|
|
||||
|
||||
Das f<>hrt wieder nicht zu dem gew<65>nschten Ergebnis. Da die Unterverzeichnisse
|
||||
nicht die Extension `*.pl' tragen, werden sie nicht ber<65>cksichtigt. F<>r die
|
||||
Suche in Unterverzeichnissen ziehen wir \texttt{find} (Siehe Abschnitt
|
||||
\ref{find}) heran:
|
||||
|
||||
\texttt{find . -name \textbackslash*.pl -exec grep \{\} \textbackslash;}
|
||||
\lstinline|find . -name \*.pl -exec grep strict {} \;|
|
||||
|
||||
Dieser Befehl gibt uns zwar die gefundenen Zeilen aus, nicht aber die Namen der
|
||||
Dateien. Es sieht f<>r \texttt{grep} so aus als ob nur eine Datei durchsucht
|
||||
@ -490,7 +466,7 @@ Parameter \texttt{-l}, allerdings w
|
||||
angezeigt. Eine Ausgabe mit beiden Informationen erhalten wir mit dem folgenden
|
||||
Konstrukt:
|
||||
|
||||
\texttt{find . -name \textbackslash*.pl -exec grep strict /dev/null \{\} \textbackslash;}
|
||||
\lstinline|find . -name \*.pl -exec grep strict /dev/null {} \;|
|
||||
|
||||
Hier durchsucht \texttt{grep} nicht nur die gefundenen Dateien, sondern bei
|
||||
jedem Aufruf auch \texttt{/dev/null}, also den digitalen M<>lleimer der per
|
||||
|
@ -57,8 +57,7 @@ z
|
||||
|
||||
Folgendes Skript funktioniert nicht:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
count=0
|
||||
cat /etc/passwd | while read i; do
|
||||
@ -69,8 +68,7 @@ cat /etc/passwd | while read i; do
|
||||
fi
|
||||
done
|
||||
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
Was ist passiert?
|
||||
|
||||
@ -91,8 +89,7 @@ praktisch nur lokal zur Verf
|
||||
Neben der Methode in \ref{daten_hochreichen} bietet sich hier eine viel
|
||||
einfachere L<>sung an:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
count=0
|
||||
while read i; do
|
||||
@ -103,8 +100,7 @@ while read i; do
|
||||
fi
|
||||
done < /etc/passwd
|
||||
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
Hier befindet sich die Schleife nicht in einer Pipe, daher wird sie auch nicht
|
||||
in einer Subshell ausgef<65>hrt. Man kann auf das \texttt{cat}-Kommando verzichten
|
||||
@ -124,7 +120,7 @@ enthalten.
|
||||
|
||||
Der erste Versuch an der Stelle wird etwas in der Form
|
||||
|
||||
\texttt{grep }\textit{wichtig datei.txt}\texttt{ > }\textit{datei.txt}
|
||||
\lstinline|grep wichtig datei.txt > datei.txt|
|
||||
|
||||
sein. Das kann funktionieren, es kann aber auch in die sprichw<68>rtliche Hose
|
||||
gehen. Das Problem an der Stelle ist, da<64> die Datei an der Stelle gleichzeitig
|
||||
@ -136,15 +132,13 @@ Dateisystem entfernt, wenn kein Deskriptor mehr auf sie zeigt. Dann kann aus
|
||||
dem gerade angelegten Deskriptor gelesen werden, w<>hrend eine neue Datei unter
|
||||
dem alten Namen angelegt wird:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
FILE=datei.txt
|
||||
exec 3< "$FILE"
|
||||
rm "$FILE"
|
||||
grep "wichtig" <&3 > "$FILE"
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
Allerdings sollte man bei dieser Methode beachten, da<64> man im Falle eines
|
||||
Fehlers die Quelldaten verliert, da die Datei ja bereits gel<65>scht wurde.
|
||||
|
11
shell.tex
11
shell.tex
@ -45,6 +45,17 @@
|
||||
\usepackage{fancybox} % K<>stchen f<>r Tastendarstellung
|
||||
|
||||
\usepackage{moreverb} % F<>r Listings
|
||||
\usepackage{listings} % F<>r Listings
|
||||
\lstset{
|
||||
extendedchars=true,
|
||||
backgroundcolor=\color[gray]{0.95},
|
||||
basicstyle=\ttfamily\scriptsize,
|
||||
numbers=left,
|
||||
numberstyle=\tiny,
|
||||
stepnumber=2,
|
||||
numbersep=5pt
|
||||
}
|
||||
|
||||
|
||||
% F<>r PDF
|
||||
\usepackage[
|
||||
|
@ -10,10 +10,10 @@
|
||||
|
||||
\texttt{-c} & Anzahl der Vorkommnisse vor die Zeilen schreiben \tabularnewline\STRUT
|
||||
\texttt{-d} & Nur doppelte Zeilen ausgeben, jede nur einmal \tabularnewline\STRUT
|
||||
\texttt{-D} & Alle doppelten Zeilen ausgeben \tabularnewline\STRUT
|
||||
\texttt{-D} & GNU-Erweiterung: Alle doppelten Zeilen ausgeben \tabularnewline\STRUT
|
||||
\texttt{-f }\textsl{n} & Die ersten \textsl{n} Felder ignorieren \tabularnewline\STRUT
|
||||
\texttt{-i} & Gro<72>- / Kleinschreibung ignorieren \tabularnewline\STRUT
|
||||
\texttt{-i} & GNU-Erweiterung: Gro<72>- / Kleinschreibung ignorieren \tabularnewline\STRUT
|
||||
\texttt{-s }\textsl{n} & Die ersten \textsl{n} Zeichen ignorieren \tabularnewline\STRUT
|
||||
\texttt{-u} & Nur einfach vorkommende Zeilen ausgeben \tabularnewline\STRUT
|
||||
\texttt{-w }\textsl{n} & Nur die ersten \textsl{n} Zeichen betrachten
|
||||
\texttt{-w }\textsl{n} & GNU-Erweiterung: Nur die ersten \textsl{n} Zeichen betrachten
|
||||
\end{longtable}
|
||||
|
@ -1,5 +1,6 @@
|
||||
% $Id$
|
||||
\chapter{Werkzeugkasten}\label{werkzeugkasten}
|
||||
|
||||
Durch die gezeigten Steuerungsm<73>glichkeiten stehen dem Shell-Pro\-grammie\-rer
|
||||
M<EFBFBD>g\-lich\-kei\-ten offen, fast alle g<>ngigen Algorithmen zu implementieren. Es
|
||||
ist tats<74>chlich in der Shell m<>glich, Sortier- oder Suchfunktionen zu
|
||||
@ -43,6 +44,14 @@ typische Aufgaben beschrieben. Diese enthalten `Links' zu den in Frage
|
||||
kommenden Werkzeugen. Danach gibt es eine alphabetische Aufz<66>hlung der
|
||||
wichtigsten Kommandos.
|
||||
|
||||
Das GNU-Projekt\marginpar{GNU!} hat vielen Kommandos n<>tzliche Parameter
|
||||
zugef<EFBFBD>gt, einige der hier beschriebenen Tools stehen ausschlie<69>lich auf
|
||||
GNU-Systemen zur Verf<72>gung. Da diese Optionen nicht auf allen Unix-Systemen zur
|
||||
Verf<EFBFBD>gung stehen, werden die betroffenen Stellen wie dieser Absatz am Rand mit
|
||||
`GNU!' markiert. Wenn diese Kommandos und Optionen benutzt werden mu<6D> also das
|
||||
Zielsystem ber<65>cksichtigt werden, im Zweifelsfall sollten die Skripte
|
||||
ausf<EFBFBD>hrlich getestet werden.
|
||||
|
||||
\section{N<EFBFBD>gel...}\label{naegel}
|
||||
|
||||
\subsection{Ein- und Ausgabe}\label{ein_und_ausgabe}
|
||||
@ -66,6 +75,7 @@ Dateien auf der Festplatte.
|
||||
\item \texttt{echo} (\ref{echo}): Daten ausgeben
|
||||
\item \texttt{grep} (\ref{grep}): In Dateien suchen
|
||||
\item \texttt{head} (\ref{head}): Dateianfang ausgeben
|
||||
\item \texttt{logger} (\ref{logger}): Text ins System-Log schreiben
|
||||
\item \texttt{printf} (\ref{printf}): Formatierte Datenausgabe
|
||||
\item \texttt{read} (\ref{read}): Zeilen einlesen
|
||||
\item \texttt{tail} (\ref{tail}): Dateiende ausgeben
|
||||
@ -215,8 +225,7 @@ Eine weitere Gemeinsamkeit ist die Art der Ein- und Ausgabe. Wenn eine
|
||||
Eingabedatei angegeben wird, wird diese verarbeitet. Ansonsten wird die
|
||||
Standard-Eingabe gelesen. Ausgaben erfolgen immer auf der Standard-Ausgabe.
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
# Aufruf als Filter:
|
||||
kommando1 | awk '{ print $1; print $2 }' | kommando2
|
||||
|
||||
@ -233,15 +242,14 @@ awk '
|
||||
# Alternativ k<>nnen die Kommandos auch in eine eigene Datei gespeichert und
|
||||
# <20>ber den Parameter -f eingebunden werden:
|
||||
awk -f script.awk datei.txt
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
Neben dem Parameter \texttt{-f} zum Einlesen der Programmdatei gibt es noch den
|
||||
Parameter \texttt{-F} mit dem der Feld-Trenner angegeben werden kann. Die
|
||||
folgende Zeile gibt beispielsweise alle Benutzernamen und deren User-IDs aus
|
||||
der Doppelpunktseparierten Datei \texttt{/etc/passwd} aus:
|
||||
|
||||
\texttt{awk -F: '\{ print \$1\dq hat ID \dq\$3 \}' /etc/passwd}
|
||||
\lstinline|awk -F: '{ print $1" hat ID "$3 }' /etc/passwd|
|
||||
|
||||
\subsubsection{Muster und Prozeduren}
|
||||
|
||||
@ -291,8 +299,7 @@ mit den TeX-Dateien weiter unten.
|
||||
|
||||
Hier ein paar Einfache Beispiele f<>r Blocks aus Mustern und Prozeduren:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
# Das erste Feld jeder Zeile ausgeben:
|
||||
{ print $1 }
|
||||
|
||||
@ -335,8 +342,7 @@ END { summe /= 1024; print "Die Gr
|
||||
# ausgeben, verarbeitet die Ausgabe von 'df':
|
||||
BEGIN { OFS="|" }
|
||||
/^\/dev\// { print $1,$5 }
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
\index{awk=\texttt{awk}|)}
|
||||
|
||||
@ -377,17 +383,17 @@ an vielen, teilweise sehr unterschiedlich gelagerten Aufgaben wertvolle
|
||||
Dienste.
|
||||
|
||||
Durch Umlenklung der Ausgabe k<>nnen Dateien erzeugt und erweitert werden. So
|
||||
k<EFBFBD>nnen mehrere Dateien per \texttt{cat datei1.txt datei2.txt > datei.txt}
|
||||
k<EFBFBD>nnen mehrere Dateien per \lstinline|cat datei1.txt datei2.txt > datei.txt|
|
||||
verkettet werden.
|
||||
|
||||
Au<EFBFBD>erdem kann man mit einem Aufruf in der Art \texttt{cat datei.txt | kommando}
|
||||
Daten an ein Programm <20>bergeben, das nur von der Standardeingabe lesen kann
|
||||
(Filter).
|
||||
Au<EFBFBD>erdem kann man mit einem Aufruf in der Art
|
||||
\lstinline|cat datei.txt | kommando| Daten an ein Programm <20>bergeben, das nur
|
||||
von der Standardeingabe lesen kann (Filter).
|
||||
|
||||
\texttt{cat} verf<72>gt <20>ber eine Reihe von Parametern, um die Ausgabe zu
|
||||
formatieren, so k<>nnen mit \texttt{-n} bzw. \texttt{-b} die Zeilen numeriert
|
||||
werden, oder mit \texttt{-s} mehrere Zeilen zu einer einzigen zusammengefa<66>t
|
||||
werden.
|
||||
GNU-\texttt{cat}\marginpar{GNU!} verf<72>gt <20>ber eine Reihe von Parametern, um die
|
||||
Ausgabe zu formatieren, so k<>nnen mit \texttt{-n} bzw. \texttt{-b} die Zeilen
|
||||
numeriert werden, oder mit \texttt{-s} mehrere Zeilen zu einer einzigen
|
||||
zusammengefa<EFBFBD>t werden.
|
||||
|
||||
\index{cat=\texttt{cat}|)}
|
||||
|
||||
@ -458,8 +464,9 @@ Zur Verdeutlichung ein paar Beispiele, wo es m
|
||||
|
||||
\LTXtable{\textwidth}{tab_kommandos_chmod_beispiele.tex}
|
||||
|
||||
Am wichtigsten sind also die Aufrufe \texttt{chmod 644 datei} und \texttt{chmod
|
||||
755 datei}, je nachdem ob die Datei ausf<73>hrbar sein soll oder nicht.
|
||||
Am wichtigsten sind also die Aufrufe \lstinline|chmod 644 datei| und
|
||||
\lstinline|chmod 755 datei|, je nachdem ob die Datei ausf<73>hrbar sein soll oder
|
||||
nicht.
|
||||
|
||||
\index{chmod=\texttt{chmod}|)}
|
||||
|
||||
@ -482,9 +489,9 @@ Will man lediglich die Gruppen-ID
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{chpasswd}\index{chpasswd=\texttt{chpasswd}|(textbf}
|
||||
\subsection{chpasswd}\index{chpasswd=\texttt{chpasswd}|(textbf}\marginpar{GNU!}
|
||||
|
||||
Mit diesem Kommando bietet sich dem Administrator des Systems die
|
||||
Mit diesem GNU-Kommando bietet sich dem Administrator des Systems die
|
||||
M<EFBFBD>g\-lich\-keit, scriptgesteuert die Pa<50>w<EFBFBD>rter f<>r neue Benutzer zu vergeben.
|
||||
Manuell <20>ndert man ein Pa<50>wort mit dem Kommando
|
||||
\texttt{passwd}\index{passwd=\texttt{passwd}}, allerdings l<>scht (flusht)
|
||||
@ -511,7 +518,23 @@ diese Datei nicht allgemein lesbar ist.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{cmp}\label{cmp}\index{cmp=\texttt{cmp}|(textbf}
|
||||
|
||||
TODO!!! cmp GNU?
|
||||
Mit \texttt{cmp} werden zwei Dateien verglichen. Wenn die beiden Dateien
|
||||
identisch sind gibt es keine Ausgabe, ansonsten wird die Position des ersten
|
||||
Unterschiedes ausgegeben.
|
||||
|
||||
Einer der beiden anzugebenden Dateinamen kann auch durch \texttt{-} ersetzt
|
||||
werden, dann wird die Standard-Eingabe mit der anderen angegebenen Datei
|
||||
verglichen.
|
||||
|
||||
Mit dem Parameter \texttt{-l} werden alle abweichenden Bytes aufgelistet,
|
||||
jeweils mit der Position (dezimal) und den beiden Bytes (oktal).
|
||||
|
||||
Durch \texttt{-s} l<><6C>t sich die Ausgabe von Unterschieden unterdr<64>cken, der
|
||||
Exit-Status gibt weiterhin das Ergebnis an.
|
||||
|
||||
In der GNU-Version\marginpar{GNU!} gibt es auch Parameter, mit denen Bereiche
|
||||
der Datei vom Vergleich ausgeschlossen werden k<>nnen (\texttt{-i}), oder mit
|
||||
denen nur die ersten n Bytes der Dateien verglichen werden (\texttt{-n}).
|
||||
|
||||
\index{cmp=\texttt{cmp}|)}
|
||||
|
||||
@ -552,7 +575,15 @@ Dateien in Spalten zusammengef
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{diff}\label{diff}\index{diff=\texttt{diff}|(textbf}
|
||||
|
||||
TODO!!! diff
|
||||
Mit \texttt{diff} werden zwei Dateien verglichen, und die <20>nderungen auf der
|
||||
Standardausgabe aufgelistet, die n<>tig sind um die erste an die zweite Datei
|
||||
anzupassen.
|
||||
|
||||
Mit dem Parameter \texttt{-r} k<>nnen auch ganze Verzeichnisse rekursiv
|
||||
verglichen werden.
|
||||
|
||||
Die ausgegebenen Listen k<>nnen mit dem \texttt{patch}-Kommando auf Dateien
|
||||
angewandt werden um sie auf den ge<67>nderten Stand zu bringen.
|
||||
|
||||
\index{diff=\texttt{diff}|)}
|
||||
|
||||
@ -602,7 +633,7 @@ Variablen zu bilden.
|
||||
|
||||
Eine wichtige Anwendung f<>r dieses Kommando ist der Fall, wenn eigentlich ein
|
||||
Array\index{Array} gebraucht w<>rde. Der Inhalt eines Array-Elements kann
|
||||
beispielsweise mittels \texttt{eval echo \textbackslash\$arr\$index} ausgegeben
|
||||
beispielsweise mittels \lstinline|eval echo \$arr$index| ausgegeben
|
||||
werden, dabei ist \texttt{arr} der Name des Arrays und \texttt{index} der Name
|
||||
der Variablen, die den Index des auszugebenden Elementes enth<74>lt.
|
||||
|
||||
@ -625,7 +656,7 @@ wichtigsten Operatoren lauten wie folgt:
|
||||
|
||||
Bei einigen Sonderzeichen ist deren Bedeutung in der Shell zu ber<65>cksichtigen,
|
||||
sie sind also durch Anf<6E>hrungszeichen oder Backslashes zu quoten:
|
||||
\texttt{i=`expr \$i \textbackslash{}* 3`}.
|
||||
\lstinline|i=`expr $i \* 3`|.
|
||||
|
||||
Eine andere M<>glichkeit f<>r einfache Rechnungen besteht in der sogenannten
|
||||
Arith\-me\-tik-Ex\-pan\-sion (Siehe \ref{arithmetikexpansion}).
|
||||
@ -666,8 +697,7 @@ Vorkommen gr
|
||||
Da die reine Beschreibung der Parameter manchmal etwas verwirrend ist, folgen
|
||||
hier ein paar praktische Beispiele:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
# Suche alle Eintr<74>ge in bzw. unter dem aktuellen Verzeichnis:
|
||||
find .
|
||||
# Suche alle normalen Dateien mit der Endung txt unter /home:
|
||||
@ -680,8 +710,7 @@ find ~ -size +10000000c -exec ls -l {} \;
|
||||
# Suche alle Eintr<74>ge im Homeverzeichnis, die innerhalb der letzten zwei Tage
|
||||
# ge<67>ndert wurden:
|
||||
find ~ -mtime -2
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
Wenn mittels \texttt{-exec} weitere Kommandos gestartet werden, sollte beachtet
|
||||
werden da<64> mindestens ein Proze<7A> pro Fundstelle gestartet wird. Das kostet sehr
|
||||
@ -755,8 +784,7 @@ Daneben stehen noch eine Reihe weiterer Signale zur Verf
|
||||
Es gibt verschiedene Wege, das Signal abzusetzen. Welchen man w<>hlt ist
|
||||
Geschmackssache. Hier ein paar Beispiele:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
# Die folgenden Befehle sind gleichwertig. Alle senden ein HUP an Proze<7A>-ID 42:
|
||||
kill -1 42
|
||||
kill -HUP 42
|
||||
@ -770,8 +798,7 @@ kill -9 -1
|
||||
|
||||
# SIGTERM an mehrere Prozesse senden:
|
||||
kill 123 456 789
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
Siehe auch: Das Beispiel `Fallensteller' in Abschnitt \ref{traps} zeigt, wie
|
||||
ein Skript auf Signale reagieren kann.
|
||||
@ -780,12 +807,12 @@ ein Skript auf Signale reagieren kann.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{killall}\label{killall}\index{killall=\texttt{killall}|(textbf}
|
||||
\subsection{killall}\label{killall}\index{killall=\texttt{killall}|(textbf}\marginpar{GNU!}
|
||||
|
||||
Im Abschnitt <20>ber \texttt{kill} (\ref{kill}) wird beschrieben, wie man ein
|
||||
Signal an einen Proze<7A> schickt, dessen ID bekannt ist. Kennt man die ID nicht,
|
||||
oder will man das Signal an mehrere Prozesse schicken, kann dieses Kommando
|
||||
eine gro<72>e Hilfe darstellen.
|
||||
oder will man das Signal an mehrere Prozesse schicken, kann dieses Kommando auf
|
||||
GNU-Systemen eine gro<72>e Hilfe darstellen.
|
||||
|
||||
Mit dem Parameter \texttt{-i} wird vor jedem Signal interaktiv gefragt, ob es
|
||||
geschickt werden soll. Mit \texttt{-v} wird angegeben, ob die Signale
|
||||
@ -803,6 +830,22 @@ zur Verf
|
||||
\index{killall=\texttt{killall}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{logger}\label{logger}\index{logger=\texttt{logger}|(textbf}
|
||||
|
||||
Mit \texttt{logger} werden Nachrichten an die Log-Mechanismen des Systems
|
||||
geschickt. So k<>nnen auch unbeobachtet laufende Skripte <20>ber ihr tun
|
||||
informieren.
|
||||
|
||||
Der zu loggende Text wird einfach als Parameter <20>bergeben.
|
||||
|
||||
Die GNU-Version\marginpar{GNU!} verf<72>gt <20>ber einige Parameter, unter anderem
|
||||
kann die Nachricht mit \texttt{-s} parallel zum System-Log auch auf der
|
||||
Standard-Fehlerausgabe ausgegeben werden.
|
||||
|
||||
\index{logger=\texttt{logger}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{ls}\label{ls}\index{ls=\texttt{ls}|(textbf}
|
||||
|
||||
@ -812,7 +855,7 @@ oder angegebenen Verzeichnis auf, das Kommando hat aber auch sehr viele
|
||||
Parameter mit denen sich die Ausgabe anpassen l<><6C>t. Hier sind die wichtigsten,
|
||||
eine vollst<73>ndige Auflistung bietet wie immer die Man-Page:
|
||||
|
||||
\LTXtable{\textwidth}{tab_kommandos_ls_parameter.tex}
|
||||
\marginpar{GNU!}\LTXtable{\textwidth}{tab_kommandos_ls_parameter.tex}
|
||||
|
||||
Besonders informativ gibt sich der Parameter \texttt{-l}, da damit auch die
|
||||
Eigent<EFBFBD>mer und die Berechtigungen der Dateien angezeigt werden. Die Ausgabe hat
|
||||
@ -893,7 +936,7 @@ gedreht.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{pgrep}\label{pgrep}\index{pgrep=\texttt{pgrep}|(textbf}
|
||||
\subsection{pgrep}\label{pgrep}\index{pgrep=\texttt{pgrep}|(textbf}\marginpar{GNU!}
|
||||
|
||||
Eine h<>ufig wiederkehrende Aufgabe ist es, zu sehen ob ein bestimmter Proze<7A>
|
||||
existiert oder nicht. Falls das Kommando \texttt{pgrep} zur Verf<72>gung steht,
|
||||
@ -901,7 +944,7 @@ kannn man auf das Konstrukt mit \texttt{ps} und \texttt{grep} verzichten. Der
|
||||
folgende Aufruf liefert alle Proze<7A>-IDs, deren Name httpd enth<74>lt, inclusive
|
||||
des vollen Kommandos:
|
||||
|
||||
\texttt{pgrep -lf httpd}
|
||||
\lstinline|pgrep -lf httpd|
|
||||
|
||||
<EFBFBD>ber weitere Parameter l<><6C>t sich genauer spezifizieren, wonach gesucht werden
|
||||
soll, hier die wichtigsten:
|
||||
@ -912,7 +955,7 @@ Die Ausgabe enth
|
||||
sich als Parameter f<>r andere Programme benutzen. Das folgende Beispiel liefert
|
||||
detaillierte Informationen <20>ber alle xterm-Prozesse:
|
||||
|
||||
\texttt{ps -fp \$(pgrep -d, -x xterm)}
|
||||
\lstinline|ps -fp $(pgrep -d, -x xterm)|
|
||||
|
||||
Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}.
|
||||
|
||||
@ -920,7 +963,7 @@ Siehe auch: Abschnitt \ref{beispiele_suchen_prozesse}.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{pkill}\label{pkill}\index{pkill=\texttt{pkill}|(textbf}
|
||||
\subsection{pkill}\label{pkill}\index{pkill=\texttt{pkill}|(textbf}\marginpar{GNU!}
|
||||
|
||||
Dieses Kommando ist eng verwandt mit \texttt{pgrep} (Siehe Abschnitt
|
||||
\ref{pgrep}), es versteht im Wesentlichen die gleichen Parameter. Allerdings
|
||||
@ -934,7 +977,7 @@ diese Funktion wird im Abschnitt zu \texttt{kill} (\ref{kill}) n
|
||||
beschrieben. Das folgende Kommando veranla<6C>t beispielsweise den Syslog-Daemon,
|
||||
seine Konfiguration neu einzulesen:
|
||||
|
||||
\texttt{pkill -HUP syslogd}
|
||||
\lstinline|pkill -HUP syslogd|
|
||||
|
||||
Das Kommando \texttt{killall} (Abschnitt \ref{killall}) bietet eine <20>hnliche
|
||||
Funktionalit<EFBFBD>t, allerdings fehlen ihm einige Parameter. Trotzdem sollte im
|
||||
@ -954,7 +997,7 @@ Dabei enth
|
||||
bestimmten Regeln durch die Daten ersetzt werden.
|
||||
|
||||
Der Format-String folgt im Wesentlichen den gleichen Regeln wie in der
|
||||
C-Version. N<>heres dazu erf<72>hrt man mit \texttt{man 3 printf}.
|
||||
C-Version. N<>heres dazu erf<72>hrt man mit \lstinline|man 3 printf|.
|
||||
|
||||
Hier die wichtigsten Parameter f<>r den Format-String:
|
||||
|
||||
@ -965,15 +1008,13 @@ Daten. Im folgenden Beispiel werden alle Benutzernamen, deren
|
||||
Home-Verzeichnisse und Default-Shells aus der Datei \texttt{/etc/passwd}
|
||||
extrahiert und <20>bersichtlich ausgegeben:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
#!/bin/sh
|
||||
IFS=:
|
||||
while read user pass uid gid name home shell; do
|
||||
printf "%-15s %-25s %s\n" $user $home $shell
|
||||
done < /etc/passwd
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
Zur Erinnerung: Die vordefinierte Variable
|
||||
\texttt{\$IFS}\index{\$IFS=\texttt{\$IFS}} ist der Feld-Separator, die
|
||||
@ -1001,12 +1042,12 @@ In Skripten m
|
||||
aktiv ist, ob also zum Beispiel ein bestimmter Serverdienst l<>uft. Dazu macht
|
||||
man \texttt{ps} <20>ber Optionen gespr<70>chiger.
|
||||
|
||||
Das Kommando versteht in der GNU-Version zwei unterschiedliche Arten von
|
||||
Optionen. Den sogenannten Unix- bzw. Posix-Stil und den BSD-Stil. Zus<75>tzlich
|
||||
gibt es noch ausf<73>hrliche Parameter, aber die sollen hier nicht beschrieben
|
||||
werden. Die jeweiligen Formen stehen nicht auf allen Systemen zur Verf<72>gung,
|
||||
wenn ein Skript beispielsweise auch unter Solaris benutzt werden soll ist man
|
||||
gezwungen, die Unix-Parametrisierung zu benutzen.
|
||||
Das Kommando versteht in der GNU-Version\marginpar{GNU!} zwei unterschiedliche
|
||||
Arten von Optionen. Den sogenannten Unix- bzw. Posix-Stil und den BSD-Stil.
|
||||
Zus<EFBFBD>tzlich gibt es noch ausf<73>hrliche Parameter, aber die sollen hier nicht
|
||||
beschrieben werden. Die jeweiligen Formen stehen nicht auf allen Systemen zur
|
||||
Verf<EFBFBD>gung, wenn ein Skript beispielsweise auch unter Solaris benutzt werden
|
||||
soll ist man gezwungen, die Unix-Parametrisierung zu benutzen.
|
||||
|
||||
Unix-Parameter zeichnen sich durch die <20>bliche Angabe mit Bindestrich aus.
|
||||
BSD-Pa\-ra\-me\-ter werden ohne Bindestrich angegeben, was neben den meisten
|
||||
@ -1016,8 +1057,7 @@ Es gibt sehr viele verschiedene Parameter, die beste Informationsquelle ist wie
|
||||
immer die Man-Page bzw. ein entsprechendes Buch. Hier werden nur ein paar
|
||||
typische Aufrufbeispiele gezeigt, deren Ausgabe sich jeder selber ansehen kann:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
# Alle Prozesse auflisten, Unix-Syntax:
|
||||
ps -e
|
||||
ps -ef
|
||||
@ -1041,8 +1081,7 @@ ps -C syslogd -o pid=
|
||||
|
||||
# Nur den Namen des Prozesses mit der ID 42 ausgeben:
|
||||
ps -p 42 -o comm=
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
F<EFBFBD>r die Suche nach Prozessen bestimmten Namens steht auf manchen Systemen auch
|
||||
das Kommando \texttt{pgrep} (Abschnitt \ref{pgrep}) zur Verf<72>gung.
|
||||
@ -1070,36 +1109,38 @@ alle Zeichen, die in der vordefinierten Variable
|
||||
Wenn keine Variablennamen angegeben werden, wird die Eingabe in der Variable
|
||||
\texttt{REPLY} abgelegt.
|
||||
|
||||
Normalerweise wird eine Eingabezeile mit einem Newline abgeschlossen. Mit dem
|
||||
Parameter \texttt{-d} ist es m<>glich, ein anderes Zeilenendezeichen anzugeben.
|
||||
Beispielsweise liest \texttt{read -d \dq~\dq~var} alle Zeichen bis zum ersten
|
||||
Leerzeichen in die Variable \texttt{var} ein.
|
||||
|
||||
Wenn nur eine bestimmte Zahl von Zeichen gelesen werden soll, kann diese durch
|
||||
den Parameter \texttt{-n} angegeben werden. Der Befehl \texttt{read -n 5 var}
|
||||
liest die ersten f<>nf Zeichen in die Variable \texttt{var} ein. Demzufolge kann
|
||||
ein Skript durch ein \texttt{read -n 1} dazu gebracht werden, auf einen
|
||||
einzelnen Tastendruck~--~nicht zwingend ein Return~--~zu warten.
|
||||
|
||||
Mit dem Parameter \texttt{-p} kann man einen Prompt, also eine
|
||||
Eingabeaufforderung ausgeben lassen. \texttt{read -p \dq{}Gib was ein:\dq~var}
|
||||
schreibt also erst den Text \textit{Gib was ein:} auf das Terminal, bevor die
|
||||
Eingaben in die Variable \texttt{var} <20>bernommen werden. Dieser Prompt wird nur
|
||||
an einem interaktiven Terminal ausgegeben, also nicht in einem Skript das seine
|
||||
Eingaben aus einer Datei oder aus einem Stream erh<72>lt.
|
||||
|
||||
Sonderzeichen k<>nnen w<>hrend der Eingabe normalerweise mittels eines Backslash
|
||||
vor der Interpretation gesch<63>tzt werden. Ein Backslash vor einem Newline
|
||||
bewirkt also eine mehrzeilige Eingabe. Dieses Verhalten kann mit dem Parameter
|
||||
\texttt{-r} abgeschaltet werden.
|
||||
|
||||
Normalerweise wird eine Eingabezeile mit einem Newline abgeschlossen. Mit dem
|
||||
Parameter \texttt{-d}\marginpar{GNU!} ist es m<>glich, ein anderes
|
||||
Zeilenendezeichen anzugeben. Beispielsweise liest
|
||||
\lstinline|read -d " " var| alle Zeichen bis zum ersten Leerzeichen in die
|
||||
Variable \texttt{var} ein.
|
||||
|
||||
Wenn nur eine bestimmte Zahl von Zeichen gelesen werden soll, kann diese durch
|
||||
den Parameter \texttt{-n}\marginpar{GNU!} angegeben werden. Der Befehl
|
||||
\lstinline|read -n 5 var| liest die ersten f<>nf Zeichen in die Variable
|
||||
\texttt{var} ein. Demzufolge kann ein Skript durch ein \lstinline|read -n 1|
|
||||
dazu gebracht werden, auf einen einzelnen Tastendruck~--~nicht zwingend ein
|
||||
Return~--~zu warten.
|
||||
|
||||
Mit dem Parameter \texttt{-p}\marginpar{GNU!} kann man einen Prompt, also eine
|
||||
Eingabeaufforderung ausgeben lassen. \lstinline|read -p "Gib was ein:" var|
|
||||
schreibt also erst den Text \textit{Gib was ein:} auf das Terminal, bevor die
|
||||
Eingaben in die Variable \texttt{var} <20>bernommen werden. Dieser Prompt wird nur
|
||||
an einem interaktiven Terminal ausgegeben, also nicht in einem Skript das seine
|
||||
Eingaben aus einer Datei oder aus einem Stream erh<72>lt.
|
||||
|
||||
Wenn die Eingabe von einem Terminal kommt und nicht auf dem Bildschirm
|
||||
erscheinen soll, zum Beispiel bei Pa<50>wortabfragen, kann die Ausgabe mit dem
|
||||
Parameter \texttt{-s} (Silent) unterdr<64>ckt werden.
|
||||
Parameter \texttt{-s}\marginpar{GNU!} (Silent) unterdr<64>ckt werden.
|
||||
|
||||
Mit \texttt{-t} kann ein Time-Out definiert werden, nach dessen Ablauf das
|
||||
Kommando mit einem Fehler abbricht. Dieser Parameter ist nur bei interaktiver
|
||||
Eingabe oder beim Lesen aus einer Pipe aktiv.
|
||||
Mit \texttt{-t}\marginpar{GNU!} kann ein Time-Out definiert werden, nach dessen
|
||||
Ablauf das Kommando mit einem Fehler abbricht. Dieser Parameter ist nur bei
|
||||
interaktiver Eingabe oder beim Lesen aus einer Pipe aktiv.
|
||||
|
||||
Der R<>ckgabewert des \texttt{read}-Kommandos ist 0, es sei denn es trat ein
|
||||
Timeout oder ein EOF auf.
|
||||
@ -1119,8 +1160,8 @@ Verzeichnisse k
|
||||
Gegensatz zu \texttt{rmdir} werden dann auch s<>mtliche enthaltenen Dateien und
|
||||
Unterverzeichnisse gel<65>scht.
|
||||
|
||||
Die GNU-Version von \texttt{rm} unterst<73>tzt zus<75>tzlich den Parameter
|
||||
\texttt{-v}, mit dem jeder L<>schvorgang ausgegeben wird.
|
||||
Die GNU-Version\marginpar{GNU!} von \texttt{rm} unterst<73>tzt zus<75>tzlich den
|
||||
Parameter \texttt{-v}, mit dem jeder L<>schvorgang ausgegeben wird.
|
||||
|
||||
\index{rm=\texttt{rm}|)}
|
||||
|
||||
@ -1142,7 +1183,7 @@ nicht-leere Verzeichnisse k
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{script}\label{script}\index{script=\texttt{script}|(textbf}
|
||||
\subsection{script}\label{script}\index{script=\texttt{script}|(textbf}\marginpar{GNU!}
|
||||
|
||||
Dieses Kommando eignet sich vorz<72>glich f<>r das Debuggen fertiger Skripte. Man
|
||||
ruft es in Verbindung mit einem Dateinamen auf. Dieser Aufruf startet eine neue
|
||||
@ -1176,8 +1217,7 @@ nur die g
|
||||
|
||||
\subsubsection{Aufruf}
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
# Aufruf als Stream-Editor:
|
||||
kommando1 | sed 's/alt/neu/' | kommando2
|
||||
|
||||
@ -1200,13 +1240,12 @@ s/alt/neu/
|
||||
# Alternativ k<>nnen die Kommandos auch in eine eigene Datei gespeichert und
|
||||
# <20>ber den Parameter -f eingebunden werden:
|
||||
sed -f script.sed datei.txt
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
Neben den oben erw<72>hnten Parametern kann \texttt{sed} auch mit \texttt{-n}
|
||||
ruhig gestellt werden. Damit werden die Zeilen nur dann ausgegeben, wenn das
|
||||
mittels `p' explizit gefordert wird. Die GNU-Version stellt noch ein paar
|
||||
Parameter zur Verf<72>gung, die Man-Page verr<72>t n<>heres.
|
||||
mittels `p' explizit gefordert wird. Die GNU-Version\marginpar{GNU!} stellt
|
||||
noch ein paar Parameter zur Verf<72>gung, die Man-Page verr<72>t n<>heres.
|
||||
|
||||
\subsubsection{Addressierung}
|
||||
|
||||
@ -1278,8 +1317,7 @@ gehen soll werden hier keine komplexen Sachen vorgestellt, sondern nur ein paar
|
||||
Einzeiler. Nichtsdestotrotz k<>nnen es auch diese unscheinbaren Aufrufe in sich
|
||||
haben.
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
### SUCHEN UND ERSETZEN
|
||||
|
||||
# Im kompletten Text 'rot' durch 'blau' ersetzen:
|
||||
@ -1355,25 +1393,24 @@ sed '/./!d' # Methode 2
|
||||
|
||||
# Alle Leerzeilen am Dateianfang l<>schen:
|
||||
sed '/./,$!d'
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
\index{sed=\texttt{sed}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{seq}\label{seq}\index{seq=\texttt{seq}|(textbf}
|
||||
\subsection{seq}\label{seq}\index{seq=\texttt{seq}|(textbf}\marginpar{GNU!}
|
||||
|
||||
Oft wird eine auf- oder absteigende Sequenz aufeinanderfolgender Zahlen
|
||||
ben<EFBFBD>tigt, beispielsweise um eine Schleife 100 mal zu durchlaufen. Es ist nicht
|
||||
sehr performant bei jedem Schleifendurchlauf hochzuz<75>hlen und dann die
|
||||
entstandene Zahl mit dem Limit zu vergleichen. Daher nimmt man an der Stelle
|
||||
\texttt{seq} zur Hilfe.
|
||||
\texttt{seq} zur Hilfe, wenn es zur Verf<72>gung steht.
|
||||
|
||||
Die zu z<>hlenden Werte werden durch drei unterschiedliche Arten der
|
||||
Parametrisierung definiert: Ein Aufruf in der Form \texttt{seq 10} gibt die
|
||||
Zahlen von 1 bis 10 aus. Mit \texttt{seq 10 20} wird von 10 bis 20 gez<65>hlt, und
|
||||
\texttt{seq 20 -2 10} z<>hlt in zweierschritten r<>ckw<6B>rts von 20 nach 10.
|
||||
Parametrisierung definiert: Ein Aufruf in der Form \lstinline|seq 10| gibt die
|
||||
Zahlen von 1 bis 10 aus. Mit \lstinline|seq 10 20| wird von 10 bis 20 gez<65>hlt,
|
||||
und \lstinline|seq 20 -2 10| z<>hlt in zweierschritten r<>ckw<6B>rts von 20 nach 10.
|
||||
|
||||
Per default kommen die Werte zeilenweise, mit dem Parameter \texttt{-s} kann
|
||||
aber auch ein anderes Trennzeichen definiert werden. Will man etwas numerieren
|
||||
@ -1390,13 +1427,13 @@ mit f
|
||||
Das Kommando \texttt{sleep} veranla<6C>t die Shell, f<>r eine angegebene Zeit zu
|
||||
warten. Die Zeit wird dabei in Sekunden angegeben.
|
||||
|
||||
In der GNU-Variante von \texttt{sleep} kann die Einheit der angegebenen
|
||||
Zeitspanne durch Suffixe definiert werden: \texttt{sleep 10s} schl<68>ft zehn
|
||||
Sekunden, \texttt{sleep 10m} zehn Minuten. Genauso werden Stunden (h) und Tage
|
||||
(d) definiert.
|
||||
In der GNU-Variante\marginpar{GNU!} von \texttt{sleep} kann die Einheit der
|
||||
angegebenen Zeitspanne durch Suffixe definiert werden: \lstinline|sleep 10s|
|
||||
schl<EFBFBD>ft zehn Sekunden, \lstinline|sleep 10m| zehn Minuten. Genauso werden
|
||||
Stunden (h) und Tage (d) definiert.
|
||||
|
||||
Au<EFBFBD>erdem kann die GNU-Variante auch mit nicht-Integer Zeiten arbeiten:
|
||||
\texttt{sleep 0.5} schl<68>ft eine halbe Sekunde.
|
||||
\lstinline|sleep 0.5| schl<68>ft eine halbe Sekunde.
|
||||
|
||||
\index{sleep=\texttt{sleep}|)}
|
||||
|
||||
@ -1447,6 +1484,9 @@ Parameter \texttt{-n} steuern.
|
||||
Mit dem Parameter \texttt{-f} (follow) gibt \texttt{tail} neue Zeilen aus,
|
||||
sobald sie an die Datei angeh<65>ngt werden.
|
||||
|
||||
Die GNU-Version\marginpar{GNU!} kann auch das Ende mehrere Dateien ausgeben
|
||||
bzw. verfolgen, wenn mehrere Namen angegeben werden.
|
||||
|
||||
\index{tail=\texttt{tail}|)}
|
||||
|
||||
|
||||
@ -1517,8 +1557,7 @@ in der Man-Page.
|
||||
|
||||
Die folgenden Beispiele verdeutlichen die Anwendung:
|
||||
|
||||
\footnotesize
|
||||
\begin{listing}[2]{1}
|
||||
\begin{lstlisting}
|
||||
text="Dies ist ein Testtext"
|
||||
|
||||
# kleine Umlaute durch grosse ersetzen:
|
||||
@ -1544,8 +1583,7 @@ echo "$text" | tr -s "a-zA-Z"
|
||||
# doppelte Buchstaben l<>schen, mit Zeichenklasse:
|
||||
echo "$text" | tr -s "[:alpha:]"
|
||||
# -> Dies ist ein Testext
|
||||
\end{listing}
|
||||
\normalsize
|
||||
\end{lstlisting}
|
||||
|
||||
\index{tr=\texttt{tr}|)}
|
||||
|
||||
@ -1564,7 +1602,7 @@ mehrere Bedingungen die zum Ausf
|
||||
Kommando gibt zm Beispiel eine Fehlermeldung aus wenn sein Skript ein Signal 1
|
||||
(HUP), 2 (INT) oder 15 (TERM) erh<72>lt:
|
||||
|
||||
\texttt{trap 'echo \dq`basename \$0`: Ooops...\dq 1>\&2' 1 2 15}
|
||||
\lstinline|trap 'echo "`basename $0`: Ooops..." 1>&2' 1 2 15|
|
||||
|
||||
Die Zeile ist dem Beispiel aus Abschnitt \ref{traps} entnommen, dort findet
|
||||
sich auch nochmal eine ausf<73>hrliche Erkl<6B>rung.
|
||||
@ -1601,13 +1639,14 @@ Weitaus h
|
||||
Zeilen z<>hlen lassen. Weiterhin kann man Bytes (\texttt{-c}) oder Zeichen
|
||||
(\texttt{-m}) z<>hlen lassen.
|
||||
|
||||
Der Parameter \texttt{-L} gibt die L<>nge der l<>ngsten enthaltenen Zeile aus.
|
||||
Der Parameter \texttt{-L} gibt in der GNU-Version \marginpar{GNU!} die L<>nge
|
||||
der l<>ngsten enthaltenen Zeile aus.
|
||||
|
||||
\index{wc=\texttt{wc}|)}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{which}\label{which}\index{which=\texttt{which}|(textbf}
|
||||
\subsection{which}\label{which}\index{which=\texttt{which}|(textbf}\marginpar{GNU!}
|
||||
|
||||
Sucht im Pfad (vordefinierte Variable
|
||||
\texttt{\$PATH}\index{\$PATH=\texttt{\$PATH}}, siehe Abschnitt
|
||||
@ -1633,8 +1672,8 @@ mit deren aktueller Konsole und der Anmeldezeit aus.
|
||||
|
||||
Bisweilen kommt man in die Verlegenheit, versehentlich zu lange Einzeiler
|
||||
geschrieben zu haben. Neben den F<>llen, in denen der Tipp-Eifer <20>berhand
|
||||
genommen hat handelt es sich in aller Regel um Zeilen in der Art `\texttt{grep
|
||||
'text' \$(find / -name \textbackslash*.txt)}'. Dieses Kommando sucht alle
|
||||
genommen hat handelt es sich in aller Regel um Zeilen in der Art
|
||||
\lstinline|grep 'text' $(find / -name \*.txt)|. Dieses Kommando sucht alle
|
||||
Dateien mit der Endung txt, die im System vorhanden sind. Diese werden `in die
|
||||
Kommandozeile eingebaut'. Wenn sehr viele Dateien gefunden werden, wird die
|
||||
Zeile zu lang f<>r die Shell\footnote{Die maximale L<>nge der Kommandozeile
|
||||
@ -1642,23 +1681,23 @@ unterscheidet sich von System zu System}.
|
||||
|
||||
Ein weiterer und in der Praxis mindestens ebenso sinnvoller Einsatzzweck ist
|
||||
das Vermeiden von Schleifen. Das obige Problem lie<69>e sich auch mit einer Zeile
|
||||
in der Form `\texttt{find / -name \textbackslash*.txt -exec grep 'text' \{\}
|
||||
\textbackslash;}'. Allerdings h<>tte das den Nachteil, da<64> f<>r jede gefundene
|
||||
Datei ein neuer \texttt{grep} gestartet werden mu<6D>. Das kostet Resourcen.
|
||||
in der Form \lstinline|find / -name \*.txt -exec grep 'text' {} \;| l<>sen.
|
||||
Allerdings h<>tte das den Nachteil, da<64> f<>r jede gefundene Datei ein neuer
|
||||
\texttt{grep} gestartet werden mu<6D>. Das kostet Resourcen.
|
||||
|
||||
Beide Probleme werden durch eine Zeile in der Form `\texttt{find / -name
|
||||
\textbackslash*.txt | xargs grep 'text'}' umgangen. Dabei liest \texttt{xargs}
|
||||
aus der Standardeingabe die Parameter, die dann an den \texttt{grep}-Aufruf
|
||||
angeh<EFBFBD>ngt werden. Sollten zu viele Dateien gefunden werden, wird \texttt{grep}
|
||||
mehrfach aufgerufen, allerdings im Gegensatz zum obigen Beispiel nicht einmal
|
||||
pro Fundstelle.
|
||||
Beide Probleme werden durch eine Zeile in der Form
|
||||
\lstinline+find / -name \*.txt | xargs grep 'text'+ umgangen. Dabei liest
|
||||
\texttt{xargs} aus der Standardeingabe die Parameter, die dann an den
|
||||
\texttt{grep}-Aufruf angeh<EFBFBD>ngt werden. Sollten zu viele Dateien gefunden
|
||||
werden, wird \texttt{grep} mehrfach aufgerufen, allerdings im Gegensatz zum
|
||||
obigen Beispiel nicht einmal pro Fundstelle.
|
||||
|
||||
Neben einigen anderen Parametern informiert die Manpage <EFBFBD>ber die Option
|
||||
\texttt{-r}. Damit kann vermieden werden, da<64> \texttt{xargs} das Kommando
|
||||
startet wenn keine Eingabe vorhanden ist. Bezogen auf das angegebene Beispiel
|
||||
w<EFBFBD>rde \texttt{grep} ohne Dateinamen gestartet, wenn \texttt{find} nichts
|
||||
findet. Es w<>rde auf Input von der Standardeingabe warten, der aber
|
||||
wahrscheinlich nicht kommt. Das Skript w<>rde h<>ngen, wenn der Parameter
|
||||
\texttt{-r} nicht angewandt w<>rde.
|
||||
Neben einigen anderen Parametern informiert die Manpage der
|
||||
GNU-Version\marginpar{GNU!} <20>ber die Option \texttt{-r}. Damit kann vermieden
|
||||
werden, da<64> \texttt{xargs} das Kommando startet wenn keine Eingabe vorhanden
|
||||
ist. Bezogen auf das angegebene Beispiel w<EFBFBD>rde \texttt{grep} ohne Dateinamen
|
||||
gestartet, wenn \texttt{find} nichts findet. Es w<>rde auf Input von der
|
||||
Standardeingabe warten, der aber wahrscheinlich nicht kommt. Das Skript w<>rde
|
||||
h<EFBFBD>ngen, wenn der Parameter \texttt{-r} nicht angewandt w<>rde.
|
||||
|
||||
\index{xargs=\texttt{xargs}|)}
|
||||
|
@ -38,21 +38,71 @@ zugleich einer der verwirrendsten Anf
|
||||
werden. Das geht mit dem Unix-Kommando
|
||||
\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
|
||||
\lstinline/chmod 755 name/, um das Skript f<>r alle Benutzer ausf<73>hrbar zu
|
||||
machen.
|
||||
|
||||
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.
|
||||
mu<EFBFBD> man der Shell noch mitteilen, wo sie zu suchen hat: Mit \lstinline|./name|
|
||||
wird versucht, im aktuellen Verzeichnis (\lstinline|./|) ein Programm namens
|
||||
\lstinline|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
|
||||
da<EFBFBD> man Skripte die immer wieder benutzt werden sollen dort ablegen kann, so
|
||||
da<EFBFBD> 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.
|
||||
kann man an der Shell durch Eingabe von \lstinline/echo $PATH/\index{\$PATH=\texttt{\$PATH}} herausfinden.
|
||||
|
||||
|
||||
\section{Fehlersuche}
|
||||
|
||||
Es gibt f<>r Shell-Skripte keine wirklichen Debugger, aber trotzdem verf<72>gt man
|
||||
<EFBFBD>ber einige bew<65>hrte Methoden zum Aufsp<73>ren von Fehlern:
|
||||
|
||||
\begin{itemize}
|
||||
|
||||
\item Debug-Ausgaben: Das wohl einfachste Mittel um herauszufinden was im
|
||||
Skript vor sich geht sind wohl regelm<6C><6D>ige Debug-Ausgaben. Dazu f<>gt man
|
||||
einfach an `strategisch wichtigen' Punkten im Skript \texttt{echo}-Zeilen ein,
|
||||
die Auskunft <20>ber den Status geben.
|
||||
|
||||
\item Syntax-Check: Wenn man das Skript in der Form
|
||||
\lstinline|sh -n ./skriptname| aufruft, wird es nicht wirklich ausgef<65>hrt.
|
||||
Lediglich die Syntax der Kommandos wird gepr<70>ft. Diese Methode findet nat<61>rlich
|
||||
keine logischen Fehler, und selbst wenn dieser Aufruf ohne Probleme durchl<68>uft
|
||||
kann sich zur Laufzeit noch ein anderer Fehler einschleichen.
|
||||
|
||||
\item \texttt{set -x}: Wenn in einem Skript der Aufruf \lstinline|set -x|
|
||||
abgesetzt wird, gibt die Shell jede Zeile nach der Expandierung aber vor der
|
||||
Ausf<EFBFBD>hrung aus. Dadurch ist klar ersichtlich wann welche Kommandos mit welchen
|
||||
Parametern ausgef<65>hrt werden. Um den Effekt wieder aufzuheben benutzt man
|
||||
\lstinline|set +x|. Man kann die Option auch auf das komplette Skript anwenden
|
||||
ohne sie in das Skript einbauen zu m<>ssen. Dazu startet man das Skript nicht
|
||||
einfach durch \lstinline|./skriptname| sondern durch
|
||||
\lstinline|sh -x ./skriptname|.
|
||||
|
||||
\item \texttt{set -v}: Dies funktioniert genau wie \lstinline|set -x|, auch der
|
||||
Aufruf <20>ber \lstinline|sh -v ./skriptname| funktioniert. Diese Option gibt jede
|
||||
Zeile vor der Ausf<73>hrung aus, allerdings im Gegensatz zu \texttt{-x} nicht in
|
||||
der expandierten sondern in der vollen Form.
|
||||
|
||||
\item System-Log: F<>r das direkte Debuggen ist dieser Weg weniger geeignet,
|
||||
aber gerade in unbeobachtet laufenden Skripten sollte man unerwartete Zust<73>nde
|
||||
oder besondere Ereignisse im System-Log festhalten. Dies geschieht mit dem
|
||||
Kommando \texttt{logger}, das in Abschnitt \ref{logger} beschrieben wird.
|
||||
|
||||
\item \texttt{script}: Mit dem Kommando \texttt{script} kann eine Sitzung an
|
||||
der Shell vollst<73>ndig protokolliert werden, inclusive aller Ein- und Ausgaben.
|
||||
Das umfa<66>t sogar Dr<44>cke auf die Pfeiltasten oder auf Backspace. So kann auch
|
||||
eine l<>ngere Sitzung mit vielen Ein- und Ausgaben nach dem Testlauf in aller
|
||||
Ruhe analysiert werden. Das Kommando wird in Abschnitt \ref{script}
|
||||
beschrieben.
|
||||
|
||||
TODO: Debuggen
|
||||
%http://localhost/~rschaten/doku/abs-guide/debugging.html#FTN.AEN14050
|
||||
%-> trapping signals
|
||||
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\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}}
|
||||
@ -84,7 +134,7 @@ verschiedenen Wert. Das wird im folgenden Beispiel deutlich:
|
||||
|
||||
Normalerweise wird man den Exit-Code nicht in dieser Form abfragen. Sinnvoller
|
||||
ist folgendes Beispiel, in dem eine Datei erst gedruckt wird, und dann~--~falls
|
||||
der Ausdruck erfolgreich war ~--~el<EFBFBD>scht wird:
|
||||
der Ausdruck erfolgreich war~--~gel<EFBFBD>scht wird:
|
||||
|
||||
\LTXtable{\textwidth}{tab_beisp_exitcode_lpr.tex}
|
||||
|
||||
@ -341,7 +391,7 @@ erzeugen.
|
||||
\section{Arithmetik-Expansion\label{arithmetikexpansion}\index{Arithmetik-Expansion|(textbf}}
|
||||
|
||||
Auch hier werden Klammern expandiert. Allerdings gleich doppelte Klammern. Mit
|
||||
einem Konstrukt in der Form \texttt{i=\$((\$i + 1))} k<>nnen einfache
|
||||
einem Konstrukt in der Form \lstinline|i=$(($i + 1))| k<>nnen einfache
|
||||
Berechnungen angestellt werden.
|
||||
|
||||
Dabei wird der Ausdruck in den Klammern bewertet als ob er in doppelten
|
||||
@ -366,9 +416,9 @@ genau eine Parent-Proze
|
||||
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.
|
||||
Diese Zusammenh<6E>nge lassen sich sehr sch<63>n durch die Ausgabe eines Kommandos
|
||||
wie \texttt{pstree} oder \lstinline|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
|
||||
@ -424,15 +474,15 @@ 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.
|
||||
Die Angabe erfolgt <20>ber eine Zeile in der Form \lstinline|#!/bin/sh|, wobei
|
||||
unter \lstinline|/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.
|
||||
moderneren Shells eingef<65>hrt um eben durch die Angabe von \lstinline|#!/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.
|
||||
|
||||
\index{Shell>Auswahl der\ldots|)}
|
||||
|
||||
@ -450,24 +500,38 @@ Dieser Befehl tut nichts, au
|
||||
|
||||
Ein Shell-Skript kann in keiner Weise Einflu<6C> auf die umgebende Shell nehmen. Das hei<65>t, da<64> es beispielsweise nicht m<>glich ist, in einem Skript Variablen zu setzen, die dann in der aufrufenden Shell zur Verf<72>gung stehen. Genauso wenig ist es m<>glich, da<64> ein Skript den Pfad <20>ndert, in dem man sich befindet. Der Grund f<>r dieses Verhalten ist die Systemsicherheit. Man will verhindern, da<64> ein Skript unbemerkt <20>nderungen an der Benutzerumgebung vornimmt.
|
||||
|
||||
Wenn es aber doch gew<65>nscht wird, da<64> ein Skript die Umgebung des Benutzers <20>ndern kann, dann mu<6D> es mit dem Source-Kommando aufgerufen werden. Das wird in der Form \verb\source skriptname\ bzw. \verb\. skriptname\ angegeben. Er bewirkt <20>hnliches wie ein \verb\#include\ in der Programmiersprache C.
|
||||
Wenn es aber doch gew<65>nscht wird, da<64> ein Skript die Umgebung des Benutzers
|
||||
<EFBFBD>ndern kann, dann mu<6D> es mit dem Source-Kommando aufgerufen werden. Das wird in
|
||||
der Form \lstinline|source skriptname| bzw. \lstinline|. skriptname| angegeben.
|
||||
Er bewirkt <20>hnliches wie ein \verb\#include\ in der Programmiersprache C.
|
||||
|
||||
Die `gesourcte' Datei wird eingelesen und ausgef<65>hrt, als ob ihr Inhalt an der Stelle des Befehls stehen w<>rde. Diese Methode wird zum Beispiel beim Login in den Konfigurationsdateien des Benutzers (z. B. \verb\.profile\, \verb\.bashrc\) oder w<>hrend des Bootvorgangs in den Init-Skripten benutzt, um immer wieder ben<65>tigte Funktionen (Starten eines Dienstes, Statusmeldungen auf dem Bildschirm etc.) in einer zentralen Datei pflegen zu k<>nnen (siehe Beispiel unter~\ref{init-skript}).
|
||||
Die `gesourcte' Datei wird eingelesen und ausgef<65>hrt, als ob ihr Inhalt an der
|
||||
Stelle des Befehls stehen w<>rde. Diese Methode wird zum Beispiel beim Login in
|
||||
den Konfigurationsdateien des Benutzers (z. B. \verb\.profile\, \verb\.bashrc\)
|
||||
oder w<>hrend des Bootvorgangs in den Init-Skripten benutzt, um immer wieder
|
||||
ben<EFBFBD>tigte Funktionen (Starten eines Dienstes, Statusmeldungen auf dem
|
||||
Bildschirm etc.) in einer zentralen Datei pflegen zu k<>nnen (siehe Beispiel
|
||||
unter~\ref{init-skript}).
|
||||
\index{source=\texttt{source}|)}
|
||||
|
||||
|
||||
\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.
|
||||
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 (\texttt{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, es sei denn man gibt mittels
|
||||
\verb\return\ (Siehe \ref{return}) explizit einen anderen Wert zur<75>ck.
|
||||
\texttt{return} (Siehe \ref{return}) explizit einen anderen Wert zur<75>ck.
|
||||
|
||||
\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
|
||||
durch die Eingabe von \texttt{count}.
|
||||
|
||||
\LTXtable{\textwidth}{tab_beisp_funktionen.tex}
|
||||
|
||||
\index{Funktion|)}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user