Chcę sposób losowego uruchomienia polecenia, powiedz 1 na 10 razy. Czy jest do tego wbudowany lub GNU coreutil, najlepiej coś takiego:
chance 10 && do_stuff
gdzie do_stuff
jest wykonywany tylko 1 na 10 razy? Wiem, że mógłbym napisać scenariusz, ale wydaje się to dość proste i zastanawiałem się, czy istnieje określony sposób.
Odpowiedzi:
W
ksh
, Bash, Zsh, Yash lub BusyBoxsh
:RANDOM
Specjalny zmienny Korn, Bash, Yash, Z i muszli BusyBox produkuje dziesiętną wartość całkowitą pseudolosowych między 0 a 32767 każdym razem jest to oceniane, więc powyższe daje (prawie) do jednego z dziesięciu przypadek.Możesz użyć tego do utworzenia funkcji, która zachowuje się tak, jak opisano w pytaniu, przynajmniej w Bash:
Zapomnienie podania argumentu lub podanie niepoprawnego argumentu da wynik 1, więc
chance && do_stuff
nigdy nie będziedo_stuff
.Wykorzystuje to ogólną formułę dla „1 in n ” przy użyciu
$RANDOM
, co[[ $RANDOM -lt $((32767 / n + 1)) ]]
daje szansę (⎣32767 / n ⎦ + 1) na 32768. Wartości,n
które nie są czynnikami 32768, wprowadzają błąd systematyczny z powodu nierównomiernego podziału w zakresie możliwych wartości.źródło
$((32767/parts+1))
była większa niż 1, lub grozi nam zwiększenie liczby części w 1, podczas gdy wynik podziału (a zatem i limitu) będzie taki sam. (cd.)(32767/n-32767/(n+1))>=1
, że rozwiązywanie dla n daje limit na ~ 181,5. W rzeczywistości liczba części może przekroczyć 194 bez problemu. Ale przy 195 częściach wynikowy limit wynosi 151, taki sam wynik jak w przypadku 194 części. Jest to niespójne i należy tego unikać. Krótko mówiąc, górna granica liczby części (n) powinna wynosić 194. Można wykonać testy limitów:[[ -z $1 || $1 -le 1 || $1 -ge 194 ]] && return 1
Niestandardowe rozwiązanie:
[ $(date +%1N) == 1 ] && do_stuff
Sprawdź, czy ostatnia cyfra bieżącego czasu w nanosekundach to 1!
źródło
[ $(date +%1N) == 1 ] && do_stuff
nie pojawia się w regularnych odstępach czasu, w przeciwnym razie losowość zostanie zepsuta. Pomyślwhile true; do [ $(date +1%N) == 1 ] && sleep 1; done
o abstrakcyjnym kontrprzykładzie. Niemniej jednak pomysł gry z nanosekundami jest naprawdę dobry, myślę, że goclock_getres()
), 2) Harmonogramowi nie zabrania się, na przykład, rozpoczynania szczeliny czasowej na granicy 100 nanosekund (który wprowadziłby błąd, nawet jeśli zegar ma rację), 3) Obsługiwanym sposobem uzyskiwania losowych wartości jest (zwykle) odczyt/dev/urandom
lub kontrola wartości$RANDOM
.Alternatywą dla użycia
$RANDOM
jestshuf
polecenie:wykona robotę. Przydatny również do losowego wybierania linii z pliku, np. dla listy odtwarzania muzyki.
źródło
Poprawianie pierwszej odpowiedzi i uczynienie bardziej oczywistym tego, co próbujesz osiągnąć:
źródło
$RANDOM % 10
będzie miał stronniczość, chyba że da$RANDOM
dokładnie 10 różnych wartości (co zwykle nie dzieje się w komputerze binarnym)"$RANDOM" -lt $((32767 / n + 1))
.Nie jestem pewien, czy chcesz losowości czy okresowości ... Dla okresowości:
Możesz go połączyć z powyższą sztuczką „RANDOM”, aby uzyskać coś bardziej chaotycznego, na przykład:
dla mnie w
seq 1 1000 $RANDOM
; wykonaj echo $ i; gotoweHTH :-)
źródło