Zufallszahlen hinzugefgt
This commit is contained in:
parent
ff78ec65e4
commit
136b632f8f
@ -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ällige Reihenfolge
|
||||
bringen}\label{chaoten}\index{Zufallszahlen|(}
|
||||
|
||||
Wir wollen uns einen MP3-Player programmieren, der Alle MP3-Dateien aus einem
|
||||
bestimmten Verzeichnisbaum in zufälliger Reihenfolge abspielt. Damit dieses
|
||||
Problem für uns eine Herausforderung darstellt\footnote{Denn schließ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ß wir in der Shell nur über Umwege an Zufallszahlen kommen
|
||||
können. Auf Systemen, in denen die Datei \texttt{/dev/urandom} existiert,
|
||||
liefert uns der Kernel aber schon sehr zufällige Zeichenfolgen. Diese Folgen
|
||||
kö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 ü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ß- / 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ält ein
|
||||
\texttt{tr}, der alle ungewollten Zeichen (alles, was kein Textzeichen ist) aus
|
||||
einem Datenstrom entfernt. Die Daten erhä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ä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 ändern, pipen wir die Ausgabe der Schleife durch ein \texttt{sort}.
|
||||
Da die ersten acht Zeichen jeder Zeile zufällig sind, erhalten wir so eine
|
||||
zufällige Reihenfolge der Zeilen. Jetzt müssen wir nur noch durch ein
|
||||
\texttt{cut} die zufälligen Zeichen abschneiden, und erhalten so die
|
||||
ursprüngliche Liste von Dateien in einer zufä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|)}
|
||||
|
Loading…
Reference in New Issue
Block a user