Ich möchte, dass ein Befehl zufällig ausgeführt wird, beispielsweise 1 von 10 Mal. Gibt es ein eingebautes oder GNU-Coreutil, idealerweise so etwas wie:
chance 10 && do_stuff
wo do_stuff
wird nur 1 in 10 mal ausgeführt? Ich weiß, dass ich ein Drehbuch schreiben kann, aber es scheint ziemlich einfach zu sein und ich habe mich gefragt, ob es einen definierten Weg gibt.
Antworten:
In
ksh
, Bash, Zsh, Yash oder BusyBoxsh
:Die
RANDOM
Sondervariable der Korn-, Bash-, Yash-, Z- und BusyBox-Shells erzeugt bei jeder Auswertung einen pseudozufälligen dezimalen Integer-Wert zwischen 0 und 32767, sodass die obige Option eine Eins-zu-Zehn-Chance ergibt.Sie können dies verwenden, um eine Funktion zu erzeugen, die sich wie in Ihrer Frage beschrieben verhält, zumindest in Bash:
Das Vergessen, ein Argument oder ein ungültiges Argument anzugeben, führt zu einem Ergebnis von 1, also
chance && do_stuff
niemalsdo_stuff
.Hierbei wird die allgemeine Formel für "1 in n " verwendet
$RANDOM
,[[ $RANDOM -lt $((32767 / n + 1)) ]]
wobei 32768 eine Chance von (⎣32767 / n ⎦ + 1) ergibt. Werte, bein
denen es sich nicht um Faktoren von 32768 handelt, führen aufgrund der ungleichmäßigen Aufteilung des Bereichs möglicher Werte zu einer Verzerrung.quelle
$((32767/parts+1))
die größer als 1 ist. Andernfalls besteht die Gefahr, dass sich die Anzahl der Teile um 1 erhöht, während das Ergebnis der Division (und damit das Limit) gleich ist. (Fortsetzung)(32767/n-32767/(n+1))>=1
, nach n aufzulösen, was eine Grenze bei ~ 181,5 ergibt. Tatsächlich könnte die Anzahl der Teile ohne Probleme bis zu 194 betragen. Bei 195 Teilen beträgt die resultierende Grenze 151, das gleiche Ergebnis wie bei 194 Teilen. Das ist inkongruent und sollte vermieden werden. Kurz gesagt, die Obergrenze für die Anzahl der Teile (n) sollte 194 sein. Sie können die Grenzprüfungen durchführen:[[ -z $1 || $1 -le 1 || $1 -ge 194 ]] && return 1
Sonderlösung:
[ $(date +%1N) == 1 ] && do_stuff
Überprüfen Sie, ob die letzte Ziffer der aktuellen Zeit in Nanosekunden 1 ist!
quelle
[ $(date +%1N) == 1 ] && do_stuff
nicht in regelmäßigen Abständen erfolgt, da sonst die Zufälligkeit beeinträchtigt wird. Stellen Sie sichwhile true; do [ $(date +1%N) == 1 ] && sleep 1; done
ein abstraktes Gegenbeispiel vor. Trotzdem ist die Idee, mit den Nanosekunden zu spielen, wirklich gut. Ich denke, ich werde sie verwenden, daher +1clock_getres()
). 2) Es ist dem Scheduler nicht untersagt, beispielsweise immer eine Zeitscheibe an einer 100-Nanosekunden-Grenze zu starten (was zu einer Verzerrung führen würde, selbst wenn die Uhr stimmt). 3) Der unterstützte Weg, zufällige Werte zu erhalten, besteht (normalerweise) darin,/dev/urandom
den Wert von auszulesen oder zu untersuchen$RANDOM
.Eine Alternative zur Verwendung
$RANDOM
ist dershuf
Befehl:werde den Job machen. Auch nützlich für die zufällige Auswahl von Zeilen aus einer Datei, z. für eine Musikwiedergabeliste.
quelle
Verbessern Sie die erste Antwort und machen Sie deutlich, was Sie erreichen möchten:
quelle
$RANDOM % 10
wird eine Verzerrung haben, es sei denn, die$RANDOM
erzeugt genau ein Vielfaches von 10 verschiedenen Werten (was in der Regel nicht in einem Binärcomputer vorkommt)"$RANDOM" -lt $((32767 / n + 1))
.Ich bin mir nicht sicher, ob Sie Zufälligkeit oder Periodizität wollen ... Für Periodizität:
Sie können es mit dem obigen "$ RANDOM" -Trick mischen, um etwas chaotischeres zu erzeugen, zum Beispiel:
denn ich in
seq 1 1000 $RANDOM
; mache ein Echo $ i; fertigHTH :-)
quelle