Depois de pesquisar um pouco, não consegui encontrar uma maneira simples de usar um comando shell para gerar um número inteiro decimal aleatório incluído em um intervalo específico, que está entre um mínimo e um máximo.
Eu li sobre /dev/random
, /dev/urandom
e $RANDOM
, mas nada disso pode fazer o que eu preciso.
Existe outro comando útil ou uma maneira de usar os dados anteriores?
shell
command-line
command
random
BowPark
fonte
fonte
Respostas:
No baú da ferramenta POSIX, você pode usar
awk
:Você não usar isso como uma fonte para gerar senhas ou dados secretos, por exemplo, como acontece com a maioria das
awk
implementações, o número pode ser facilmente adivinhado com base no tempo que o comando foi executado.Com muitas
awk
implementações, esse comando executado duas vezes no mesmo segundo geralmente fornece a mesma saída.fonte
x=$(awk -v min=$min_var -v max=$max_var 'BEGIN{srand(); printf("%.2d", int(min+rand()*(max-min+1)))}')
awk -v min=5 -v max=10 -v seed="$(od -An -N4 -tu4 /dev/urandom)" 'BEGIN{srand(seed+0); print int(min+rand()*(max-min+1))}'
. Você pode usar em$RANDOM
vez de,od ... /dev/random
mas seu valor inicial está no intervalo relativamente pequeno de 0 a 32767 e, portanto, provavelmente obterá repetições visíveis em sua saída ao longo do tempo.Você pode tentar
shuf
no GNU coreutils:fonte
shuf
.mínimo
No BSD e no OSX, você pode usar jot para retornar um único
-r
número aleatório ( ) do intervalomin
paramax
, inclusive.Problema de distribuição
Infelizmente, o alcance e a distribuição dos números gerados aleatoriamente são influenciados pelo fato de o jot usar aritmética de ponto flutuante de precisão dupla internamente e printf (3) para o formato de saída, o que causa problemas de arredondamento e truncamento. Portanto, os intervalos
min
emax
são gerados com menos frequência, conforme demonstrado:No OS X 10.11 (El Capitan), isso parece ter sido corrigido:
e...
Resolvendo o problema de distribuição
Para versões mais antigas do OS X, felizmente existem várias soluções alternativas. Uma é usar a conversão inteira printf (3). A única ressalva é que o intervalo máximo agora se torna
max+1
. Usando a formatação inteira, obtemos uma distribuição justa em todo o intervalo:A solução perfeita
Por fim, para obter um lançamento justo dos dados usando a solução alternativa, temos:
Lição de casa extra
Veja jot (1) para detalhes matemáticos e de formatação e muitos outros exemplos.
fonte
A
$RANDOM
variável normalmente não é uma boa maneira de gerar bons valores aleatórios. A saída da/dev/[u]random
necessidade também deve ser convertida primeiro.Uma maneira mais fácil é usar linguagens de nível superior, como por exemplo python:
Para gerar uma variável inteira aleatória entre 5 e 10 (5 <= N <= 10), use
Não use isso para aplicativos criptográficos.
fonte
Você pode obter o número aleatório através
urandom
head -200 /dev/urandom | cksum
Resultado:
3310670062 52870
Para recuperar a parte do número acima.
head -200 /dev/urandom | cksum | cut -f1 -d " "
Então a saída é
3310670062
fonte
head -200
(ou seu equivalente POSIXhead -n 100
) retorna as primeiras 200 linhas de/dev/urandom
./dev/urandom
não é um arquivo de texto, esse comando pode retornar de 200 bytes (todos os 0x0a, LF em ASCII) até o infinito (se o byte 0xa nunca for retornado), mas valores entre 45k e 55k são os mais prováveis. cksum retorna um número de 32 bits, por isso é inútil obter mais de 4 bytes/dev/urandom
.Para gerar uma variável inteira aleatória entre 5 e 10 (incluindo ambos), use
%
funciona como um operador de módulo.Provavelmente, existem maneiras melhores de converter a variável aleatória
$RANDOM
em um intervalo específico. Não use isso para aplicativos criptográficos ou nos casos em que você precisa de variáveis aleatórias reais e com igual distribuição (como para simulações).fonte
# echo $(( $RANDOM % 256 ))
produzirá um número "aleatório" entre 0-255 nos dialetos sh * modernos.fonte
Talvez o
UUID
(no Linux) possa ser usado para recuperar o número aleatórioPara obter o número aleatório entre
70
e100
fonte
Isso irá gerar um número hexadecimal de 8 dígitos.
fonte
Para permanecer totalmente dentro do bash e usar a variável $ RANDOM, mas evite a distribuição desigual:
Este exemplo forneceria números aleatórios de 20 a 29.
fonte
$r
deve ser inicializado para 65535 ou outro valor alto para evitar um[: -lt: unary operator expected
erro.A distribuição é boa:
para ((i = 1; i <= 100000; i ++)) ecoa $ ((% ALEATÓRIO (20 - 10 + 1) + 10)); feito | classificar -n | uniq -c
valor da contagem
9183 10
9109 11
8915 12
9037 13
9100 14
9138 15
9125 16
9261 17
9088 18
8996 19
9048 20
fonte