Zufallszahlen hinzugefgt
This commit is contained in:
		| @@ -336,3 +336,90 @@ esac | ||||
| 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|)} | ||||
|  | ||||
|  | ||||
| \section{Chaoten: Dateien in zuf<75>llige Reihenfolge | ||||
| bringen}\label{chaoten}\index{Zufallszahlen|(} | ||||
|  | ||||
| Wir wollen uns einen MP3-Player programmieren, der Alle MP3-Dateien aus einem | ||||
| bestimmten Verzeichnisbaum in zuf<75>lliger Reihenfolge abspielt. Damit dieses | ||||
| Problem f<>r uns eine Herausforderung darstellt\footnote{Denn schlie<69>lich hat | ||||
| mpg123 schon von Hause aus eine Random-Funktion}, wollen wir vor dem Abspielen | ||||
| der jeweiligen Datei etwas mit dem Dateinamen anstellen. Ob das eine einfache | ||||
| Ausgabe per \texttt{echo} ist, oder ob der Name per Sprachsynthese oder auf | ||||
| einem externen Display angezeigt werden soll ist an dieser Stelle egal. | ||||
|  | ||||
| Das Problem ist, da<64> wir in der Shell nur <20>ber Umwege an Zufallszahlen kommen | ||||
| k<EFBFBD>nnen. Auf Systemen, in denen die Datei \texttt{/dev/urandom} existiert, | ||||
| liefert uns der Kernel aber schon sehr zuf<75>llige Zeichenfolgen. Diese Folgen | ||||
| k<EFBFBD>nnen alle Zeichen enthalten, daher m<>ssen sie vor der Benutzung f<>r unsere | ||||
| Zwecke noch etwas 'bereinigt' werden. | ||||
|  | ||||
| Wie das aussieht, wenn es fertig ist, sieht man im folgenden Skript: | ||||
|  | ||||
| \footnotesize | ||||
| \index{!==\texttt{!=}} | ||||
| \begin{listing}[2]{1} | ||||
| #!/bin/sh | ||||
| for i in `find $1 -type f -name "*.[mM][pP]3"`; do | ||||
| \end{listing} | ||||
| \normalsize | ||||
| \begin{flushright} | ||||
| 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} | ||||
|   echo `tr -dc "[:alpha:]" < /dev/urandom | \ | ||||
|         dd count=8 bs=1 2> /dev/null`$i | ||||
| \end{listingcont} | ||||
| \normalsize | ||||
| \begin{flushright} | ||||
| 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 | ||||
| einem Datenstrom entfernt. Die Daten erh<72>lt \texttt{tr} durch die | ||||
| \texttt{<}-Umleitung aus oben genannter Datei. | ||||
|  | ||||
| Diese Datei liefert 'ohne Ende' Zeichen. Wir wollen aber nur acht Zeichen | ||||
| haben, die wir unserem Dateinamen voranstellen k<>nnen. Dazu benutzen wir das | ||||
| 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} | ||||
| done | sort | cut -b 9- | while read i; do | ||||
| \end{listingcont} | ||||
| \normalsize | ||||
| \begin{flushright} | ||||
| 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 | ||||
| Durchlauf gleich sein. | ||||
|  | ||||
| Um das zu <20>ndern, pipen wir die Ausgabe der Schleife durch ein \texttt{sort}. | ||||
| Da die ersten acht Zeichen jeder Zeile zuf<75>llig sind, erhalten wir so eine | ||||
| zuf<EFBFBD>llige Reihenfolge der Zeilen. Jetzt m<>ssen wir nur noch durch ein | ||||
| \texttt{cut} die zuf<75>lligen Zeichen abschneiden, und erhalten so die | ||||
| urspr<EFBFBD>ngliche Liste von Dateien in einer zuf<75>lligen Reihenfolge. | ||||
|  | ||||
| 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} | ||||
|   echo "Jetzt wird $i gespielt" | ||||
|   mpg123 "$i" | ||||
| done | ||||
| \end{listingcont} | ||||
| \normalsize | ||||
| \index{Zufallszahlen|)} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user