Après avoir un peu cherché Google, je ne trouvais pas de moyen simple d'utiliser une commande shell pour générer un nombre entier décimal aléatoire inclus dans une plage spécifique, comprise entre un minimum et un maximum.
Je l' ai lu /dev/random
, /dev/urandom
et $RANDOM
, mais aucun d' entre eux peuvent faire ce que je dois.
Existe-t-il une autre commande utile ou un moyen d'utiliser les données précédentes?
shell
command-line
command
random
BowPark
la source
la source
Réponses:
Dans la boîte à outils POSIX, vous pouvez utiliser
awk
:N'utilisez pas cela comme source pour générer des mots de passe ou des données secrètes, par exemple, comme dans la plupart des
awk
implémentations, le nombre peut facilement être deviné en fonction du moment où la commande a été exécutée.Avec de nombreuses
awk
implémentations, cette commande exécutée deux fois dans la même seconde vous donnera généralement le même résultat.la source
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))}'
. Vous pouvez utiliser$RANDOM
au lieu deod ... /dev/random
mais votre valeur de départ se situe dans une plage relativement petite de 0 à 32767 et vous obtiendrez donc probablement des répétitions notables dans votre sortie au fil du temps.Vous pouvez essayer
shuf
depuis GNU coreutils:la source
shuf
.iota
Sous BSD et OSX, vous pouvez utiliser jot pour renvoyer un seul nombre aléatoire (
-r
) de l’intervallemin
àmax
, inclus.Problème de distribution
Malheureusement, la portée et la distribution des nombres générés aléatoirement sont influencées par le fait que jot utilise en interne une arithmétique en virgule flottante à double précision en interne et printf (3) pour le format de sortie, ce qui entraîne des problèmes d’arrondi et de troncature. Par conséquent, les intervalles
min
etmax
sont générés moins fréquemment, comme indiqué:Sous OS X 10.11 (El Capitan), cela semble avoir été corrigé:
et...
Résoudre le problème de distribution
Heureusement, il existe plusieurs solutions de contournement pour les anciennes versions d’OS X. La première consiste à utiliser la conversion d’entiers printf (3). Le seul inconvénient est que l'intervalle maximum devient maintenant
max+1
. En utilisant le formatage entier, nous obtenons une distribution juste sur tout l'intervalle:La solution parfaite
Enfin, pour obtenir un résultat juste des dés en utilisant la solution de contournement, nous avons:
Devoir supplémentaire
Voir jot (1) pour les détails mathématiques et le formatage, ainsi que de nombreux autres exemples.
la source
La
$RANDOM
variable n’est normalement pas un bon moyen de générer de bonnes valeurs aléatoires. La sortie de/dev/[u]random
besoin doit également être convertie en premier.Un moyen plus simple consiste à utiliser des langages de niveau supérieur, comme par exemple python:
Pour générer une variable entière aléatoire comprise entre 5 et 10 (5 <= N <= 10), utilisez
Ne l'utilisez pas pour des applications cryptographiques.
la source
Vous pouvez obtenir le nombre aléatoire à travers
urandom
head -200 /dev/urandom | cksum
Sortie:
3310670062 52870
Pour récupérer une partie du numéro ci-dessus.
head -200 /dev/urandom | cksum | cut -f1 -d " "
Ensuite, la sortie est
3310670062
la source
head -200
(ou son équivalent POSIXhead -n 100
) renvoie les 200 premières lignes de/dev/urandom
./dev/urandom
n’est pas un fichier texte, cette commande peut retourner de 200 octets (tous les 0x0a, LF en ASCII) à l’infini (si l’octet 0xa n’est jamais renvoyé), mais les valeurs entre 45k et 55k sont les plus probables. cksum renvoie un nombre 32 bits, il est donc inutile d’obtenir plus de 4 octets/dev/urandom
.Pour générer une variable entière aléatoire comprise entre 5 et 10 (incluant les deux), utilisez
%
travaille comme opérateur modulo.Il existe probablement de meilleurs moyens de convertir la variable aléatoire
$RANDOM
en une plage spécifique. Ne l'utilisez pas pour des applications cryptographiques ou dans les cas où vous avez besoin de variables aléatoires réelles, à distribution égale (comme pour les simulations).la source
# echo $(( $RANDOM % 256 ))
produira un nombre "aléatoire" compris entre 0 et 255 dans les dialectes modernes * sh.la source
Peut-être que
UUID
(sous Linux) peut être utilisé pour récupérer le nombre aléatoirePour obtenir le nombre aléatoire entre
70
et100
la source
Cela générera un nombre hexadécimal long de 8 chiffres.
la source
Pour rester entièrement dans bash et utiliser la variable $ RANDOM mais éviter la distribution inégale:
Cet exemple fournirait des nombres aléatoires de 20 à 29.
la source
$r
doit être initialisé à 65535 ou à une autre valeur élevée pour éviter une[: -lt: unary operator expected
erreur.La distribution est bonne:
pour ((i = 1; i <= 100000; i ++)) echo $ ((RANDOM% (20 - 10 + 1) + 10)); fait | trier -n | uniq -c
compter la valeur
9183 10
9109 11
8915 12
9037 13
9100 14
9138 15
9125 16
9261 17
9088 18
8996 19
9048 20
la source