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.
|
Wenn \texttt{case} eine andere Parameterzahl feststellt, wird eine Meldung mit der Aufrufsyntax auf die Standard-Fehlerausgabe geschrieben.
|
||||||
\end{flushright}
|
\end{flushright}
|
||||||
\index{trap=\texttt{trap}|)}\index{Signal|)}
|
\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