Como definir uma variável para um valor aleatório com bash

14

Em um programa, preciso definir uma variável para um valor aleatório de 0 ou 1.

Não consigo descobrir como fazê-lo e o Google falhou comigo.

cheesits456
fonte

Respostas:

30

Um método fácil é usar $RANDOMpara recuperar um número inteiro pseudo-aleatório de 16 bits no intervalo [0; 32767]. Você pode simplesmente converter isso para [0; 1] calculando o módulo 2 do número aleatório:

echo $(( $RANDOM % 2 ))

Mais informações sobre o Bash $RANDOM: http://www.tldp.org/LDP/abs/html/randomvar.html

Com essa construção simples, você pode facilmente criar scripts poderosos usando aleatoriedade, como nesta história em quadrinhos ...

Commit Strip - Roleta Russa

Byte Commander
fonte
4
O pedante em mim sente a necessidade de salientar que o comando de destruição do servidor de produção escolhido não fará nada sem --no-preserve-root- então talvez não o jogo de roleta russa que eles estavam esperando ...
Boris the Spider
2
@BoristheSpider, eles estão usando a $[]sintaxe antiquada - quem sabe se eles rmtinham esse --no-preserve-rootrecurso?
Muru
10
@BoristheSpider Minha interpretação dos quadrinhos é que, quando veem a mensagem rm: it is dangerous to operate recursively on '/' rm: use --no-preserve-root to override this failsafe, eles abaixam a cabeça e, sabendo que perderam o jogo, apagam seu disco com ddhonra.
Eliah Kagan
@EliahKagan ah, seppuku. Entendido.
Boris, o Aranha
@BoristheSpider: O programa --no-preserve-rootsó foi implementado "ultimamente". Não tem informações sobre quando foi implementado, mas o IIRC tem apenas alguns anos. E isso é uma quantia pequena quando se trata de Linux. Aqui está um tíquete sobre isso: bugs.launchpad.net/ubuntu/+source/coreutils/+bug/174283
Apache
13

Você poderia usar 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

Exemplo:

$ 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
fonte
5

E se:

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

Ou até:

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

Ou talvez:

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

Ou mais hackily:

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

E também:

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

Assim como:

r=$((0x$(cut -c1-1 /proc/sys/kernel/random/uuid) % 2))
Colin Ian King
fonte
1

Este script não tem benefícios sobre as respostas existentes. Apenas para fins de entretenimento ...

Obtenha um byte /dev/urandom(embora em geral o envio de caracteres binários arbitrários para o console não seja recomendado ™ porque pode gerar resultados inesperados / confusos):

head -c 1 /dev/urandom

E transformar em número decimal:

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

E obtenha o restante de sua divisão por 2:

echo $((`head -c 1 /dev/urandom | od -An -t u1` % 2))
Sasha
fonte