Subshell-Schleifen vermeiden
This commit is contained in:
@ -46,7 +46,68 @@ TODO!!!
|
|||||||
|
|
||||||
TODO!!!
|
TODO!!!
|
||||||
|
|
||||||
\subsection{Daten aus einer Subshell hochreichen}
|
\subsection{Subshell-Schleifen vermeiden}
|
||||||
|
|
||||||
|
Wir wollen ein Skript schreiben, das die \texttt{/etc/passwd} liest und dabei
|
||||||
|
z<EFBFBD>hlt, wie viele Benutzer eine UID kleiner als 100 haben.
|
||||||
|
|
||||||
|
Folgendes Skript funktioniert nicht:
|
||||||
|
|
||||||
|
\footnotesize
|
||||||
|
\begin{listing}[2]{1}
|
||||||
|
#!/bin/sh
|
||||||
|
count=0
|
||||||
|
cat /etc/passwd | while read i; do
|
||||||
|
uid=`echo $i | cut -f 3 -d:`
|
||||||
|
if [ $uid -lt 100 ]; then
|
||||||
|
count=`expr $count + 1`
|
||||||
|
echo $count
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
||||||
|
\end{listing}
|
||||||
|
\normalsize
|
||||||
|
|
||||||
|
Was ist passiert?
|
||||||
|
|
||||||
|
Dieses Skript besteht im Wesentlichen aus einer Pipe. Wir haben ein
|
||||||
|
\texttt{cat}-Kommando, das den Inhalt der \texttt{/etc/passwd} durch eben diese
|
||||||
|
Pipe an eine Schleife <20>bergibt. Das \texttt{read}-Kommando in der Schleife
|
||||||
|
liest die einzelnen Zeilen aus, dann folgt ein Bi<42>chen Auswertung.
|
||||||
|
|
||||||
|
Es ist zu beobachten, da<64> bei der Ausgabe in Zeile 7 die Variable
|
||||||
|
\texttt{\$count} korrekte Werte enth<74>lt. Um so unverst<73>ndlicher ist es, da<64> sie
|
||||||
|
nach der Vollendung der Schleife wieder den Wert 0 enth<74>lt.
|
||||||
|
|
||||||
|
Das liegt daran, da<64> diese Schleife als Teil einer Pipe in einer Subshell
|
||||||
|
ausgef<EFBFBD>hrt wird. Die Variable \texttt{\$count} steht damit in der Schleife
|
||||||
|
praktisch nur lokal zur Verf<72>gung, sie wird nicht an das umgebende Skript
|
||||||
|
'hochgereicht'.
|
||||||
|
|
||||||
|
Neben der Methode in \ref{daten_hochreichen} bietet sich hier eine viel
|
||||||
|
einfachere L<>sung an:
|
||||||
|
|
||||||
|
\footnotesize
|
||||||
|
\begin{listing}[2]{1}
|
||||||
|
#!/bin/sh
|
||||||
|
count=0
|
||||||
|
while read i; do
|
||||||
|
uid=`echo $i | cut -f 3 -d:`
|
||||||
|
if [ $uid -lt 100 ]; then
|
||||||
|
count=`expr $count + 1`
|
||||||
|
echo $count
|
||||||
|
fi
|
||||||
|
done < /etc/passwd
|
||||||
|
echo Es sind $count Benutzer mit einer ID kleiner 100 eingetragen
|
||||||
|
\end{listing}
|
||||||
|
\normalsize
|
||||||
|
|
||||||
|
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
|
||||||
|
und den Inhalt der Datei durch die Umlenkung in Zeile 9 direkt auf die
|
||||||
|
Standardeingabe der Schleife (und somit auf das \texttt{read}-Kommando) legen.
|
||||||
|
|
||||||
|
\subsection{Daten aus einer Subshell hochreichen}\label{daten_hochreichen}
|
||||||
|
|
||||||
TODO!!!
|
TODO!!!
|
||||||
|
|
||||||
@ -81,3 +142,5 @@ grep "wichtig" <&3 > "$FILE"
|
|||||||
\end{listing}
|
\end{listing}
|
||||||
\normalsize
|
\normalsize
|
||||||
|
|
||||||
|
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.
|
||||||
|
Reference in New Issue
Block a user