Subshell-Schleifen vermeiden
This commit is contained in:
		| @@ -46,7 +46,68 @@ 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!!! | ||||
|  | ||||
| @@ -81,3 +142,5 @@ grep "wichtig" <&3 > "$FILE" | ||||
| \end{listing} | ||||
| \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