Nombre aléatoire entre de gamme dans le shell
Comment je peux générer des nombre aléatoire entre 0 et 60 en sh (/bin/sh, pas de bash)? C'est un satellite de la boîte, il n'y a pas de $RANDOM
variable, et d'autres produits [cksum, do (do -vAn -N4 -tu4 < /dev/urandom)].
Je veux randomize un crontab de l'emploi du temps.
OriginalL'auteur Adrian | 2011-01-12
Vous devez vous connecter pour publier un commentaire.
Si vous avez tr, de la tête et /dev/urandom, vous pouvez écrire ceci:
Alors vous devez utiliser le reste de l'opérateur de mettre en 0-60 gamme.
Ah. J'avais lu la question d'une telle manière de faire croire que /dev/urandom n'était pas présent. C'est une excellente solution.
Je reçois
tr: illegal byte sequence
essayez avec LANG=C avant la commande (source: stackoverflow.com/questions/11287564/... qui est pour le sed, mais j'espère que devrait fonctionner pour vous aussi)
OriginalL'auteur marco
Comment sur l'utilisation de l'nanosecondes de système de temps?
Ce n'est pas comme vous avez besoin du point de vue cryptographique numéros utiles ici.
Selon la version de
/bin/sh
il est, vous pourriez être en mesure de le faire:$((
date +%N
% 60 ))Si elle ne prend pas en charge la
$(())
la syntaxe, mais vous avez dc, vous pourriez essayer:Sans savoir de quel système d'exploitation, la version de
/bin/sh
ou quoides outils sont disponibles, il est difficile de trouver une solution garantie à travailler.
OriginalL'auteur Thedward
Avez-vous des awk? Vous pouvez appeler des awk fonction rand (). Par exemple:
Vous avez de la graine du générateur de nombres aléatoires:
awk 'BEGIN { srand(); printf("%d\n",rand()*60) }'
. Pas de redirection est nécessaire s'il n'existe qu'unBEGIN
clause.cela est vrai si vous prévoyez sur l'appel à rand() plus d'une fois par seconde. Sinon, srand() doit être automatiquement placé par le temps
awk 'BEGIN {print rand(), rand()}'; sleep 3; awk 'BEGIN {print rand(), rand()}'
me donne la même paire de valeurs deux fois pour les deux GNU awk et BusyBox awk (des valeurs différentes pour les différentes versions). Si je comprendsrand()
et même si je supprime lesleep
, les valeurs varient. Il n'est pas rare d'avoir explicitement les graines d'un générateur de nombre aléatoire. Partie de la raison pour cela est si vous pouvez obtenir une séquence prévisible au cours des essais.vous avez raison, j'ai mal lu la documentation.
OriginalL'auteur frankc
Je sais que ce post est vieux, mais les réponses proposées ne sont pas génératrices uniforme, impartiale des nombres aléatoires. L'on a accepté la réponse est essentiellement ceci:
Le problème avec cette suggestion est que, par le choix d'un nombre à 3 chiffres à partir de
/dev/urandom
, la plage est de 0 à 999, un total de 1 000 numéros. Cependant, 1000 de ne pas diviser en 60 uniformément. En tant que tel, vous allez être biaisée vers la création d'un 0-959 juste un peu plus de 960-999.La deuxième réponse, tandis que les créatifs en utilisant nanosecondes de votre horloge, souffre de la même approche partiale:
De la plage de nanosecondes est comprise entre 0 et 999,999,999, qui est de 1 milliard de dollars de chiffres. Donc, si vous êtes en divisant ce résultat par 60, vous allez de nouveau être biaisée vers la génération de 0 à 999,999,959 un peu plus de 999,999,960-999,999,999.
Tout le reste de l'réponses sont les mêmes biaisée non-uniforme de la génération.
Pour générer impartiale uniforme nombres aléatoires dans la gamme de 0 à 59 (est ce que je suppose qu'il veut dire plutôt que de 0-60, si il tente de générer aléatoirement un
crontab(1)
entrée), nous avons besoin de forcer la sortie à être un multiple de 60.Tout d'abord, nous allons générer de façon aléatoire un nombre de 32 bits entre 0 et 4294967295:
Nous allons maintenant la force de notre gamme pour être entre $MIN et 4294967295 qui est un multiple de 60:
Cela signifie:
En d'autres termes, ma gamme de [16, 4294967295] est exactement un multiple de 60. Ainsi, chaque numéro je générer la plage, puis de diviser par 60, ce sera tout aussi susceptibles que tout autre nombre. Ainsi, j'ai l'impartialité du générateur de nombres de 0 à 59 (ou 1-60 si vous ajoutez 1).
La seule chose qui reste à faire est de vous assurer que mon numéro est entre 16 et 4294967295. Si mon nombre est inférieur à 16, alors je vais avoir besoin de générer un nouveau numéro:
Tout mis ensemble pour le copier/coller goodnees:
OriginalL'auteur Aaron Toponce
La graine doit être comprise entre 0 et 65535, ce qui n'est pas un multiple de 60 ans, les minutes de 0 à 15 ont un peu plus de chance ob être choisi, mais l'écart n'est probablement pas important.
Si vous voulez atteindre la perfection, utiliser "od - - N1 -tu1" et la boucle jusqu'à ce que la valeur est inférieure à 240.
Testé avec busybox od.
OriginalL'auteur Anonymous
Marco réponse échoue à chaque fois généré numéro commence par 0 et a d'autres chiffres est supérieur à 7, tel qu'il est interprété comme octal, je propose:
spécialement dans le cas où vous souhaitez aller plus loin, par exemple pour établir une gamme:
OriginalL'auteur Javier Puche