Umformatiert

This commit is contained in:
rschaten
2004-12-10 14:38:03 +00:00
parent 15af99f29e
commit 464f0bcf77
6 changed files with 417 additions and 333 deletions

View File

@@ -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