Jak ustawić zmienną na losową wartość za pomocą bash

14

W programie muszę ustawić zmienną na losową wartość 0 lub 1.

Nie mogę wymyślić, jak to zrobić, a Google mnie zawiodło.

cheesits456
źródło

Odpowiedzi:

30

Jedną z łatwych metod jest użycie $RANDOMpseudolosowej 16-bitowej liczby całkowitej z zakresu [0; 32767]. Możesz po prostu przekonwertować to na [0; 1] obliczając moduł 2 liczby losowej:

echo $(( $RANDOM % 2 ))

Więcej informacji o Bash $RANDOM: http://www.tldp.org/LDP/abs/html/randomvar.html

Dzięki tej prostej konstrukcji możesz łatwo budować potężne skrypty przy użyciu losowości, jak w tym komiksie ...

Commit Strip - Rosyjska ruletka

Bajt Dowódca
źródło
4
Pedant we mnie odczuwa potrzebę wskazania, że ​​wybrane polecenie niszczenia serwera produkcyjnego nic nie zrobi bez --no-preserve-root- więc może nie gra w rosyjską ruletkę, na którą liczyli ...
Boris the Spider
2
@ BoristheSpider używają przestarzałej $[]składni - kto wie, czy rmmieli taką --no-preserve-rootfunkcję?
muru
10
@ BoristheSpider Moja interpretacja komiksu jest taka, że ​​kiedy widzą wiadomość rm: it is dangerous to operate recursively on '/' rm: use --no-preserve-root to override this failsafe, zwisają nisko i wiedząc, że przegrali grę, zaczynają wymazywać dysk z ddhonoru.
Eliah Kagan
@EliahKagan ah, seppuku. Zrozumiany.
Boris the Spider
@ BoristheSpider: Zaimplementowano --no-preserve-roottylko „ostatnio”. Nie mam informacji o tym, kiedy został wdrożony, ale IIRC ma zaledwie kilka lat. A to niewielka ilość, jeśli chodzi o Linuksa. Oto bilet na ten temat: bugs.launchpad.net/ubuntu/+source/coreutils/+bug/174283
Apache
13

Możesz użyć shuf

DESCRIPTION
     Write a random permutation of the input lines to standard output.

     -i, --input-range=LO-HI
            treat each number LO through HI as an input line
     -n, --head-count=COUNT
            output at most COUNT lines

Przykład:

$ foo=$(shuf -i0-1 -n1)
$ echo $foo
1
$ foo=$(shuf -i0-1 -n1)
$ echo $foo
0
$ foo=$(shuf -i0-1 -n1)
$ echo $foo
0
$ foo=$(shuf -i0-1 -n1)
$ echo $foo
1
Zanna
źródło
5

Co powiesz na:

#!/bin/bash
r=$(($RANDOM % 2))
echo $r

Lub nawet:

r=$(($(od -An -N1 -i /dev/random) % 2))

A może:

r=$(seq 0 1 | sort -R  | head -n 1)

Lub bardziej hackersko:

r=$(($(head -128 /dev/urandom | cksum | cut -c1-10) % 2))

I również:

r=$(apg -a 1 -M n -n 1 -m 8 -E 23456789  | cut -c1)

Jak również:

r=$((0x$(cut -c1-1 /proc/sys/kernel/random/uuid) % 2))
Colin Ian King
źródło
1

Ten skrypt nie ma przewagi nad istniejącymi odpowiedziami. Tylko w celach rozrywkowych ...

Pobierz jeden bajt /dev/urandom(chociaż generalnie wysyłanie dowolnych znaków binarnych do konsoli nie jest zalecane ™, ponieważ może to dawać nieoczekiwane / mylące wyniki):

head -c 1 /dev/urandom

I zamień na liczbę dziesiętną:

head -c 1 /dev/urandom | od -An -t u1

I uzyskaj pozostałą część podziału przez 2:

echo $((`head -c 1 /dev/urandom | od -An -t u1` % 2))
Sasha
źródło