Je veux un moyen d'exécuter une commande au hasard, disons 1 fois sur 10. Existe-t-il un coreutil intégré ou GNU pour ce faire, idéalement quelque chose comme:
chance 10 && do_stuff
où do_stuff
est exécuté seulement 1 fois sur 10? Je sais que je pourrais écrire un script, mais cela semble être une chose assez simple et je me demandais s'il y avait une manière définie.
Réponses:
Dans
ksh
, Bash, Zsh, Yash ou BusyBoxsh
:le
RANDOM
variable spéciale des shells Korn, Bash, Yash, Z et BusyBox produit une valeur entière décimale pseudo-aléatoire entre 0 et 32767 chaque fois qu'elle est évaluée, de sorte que ce qui précède donne (presque) une chance sur dix.Vous pouvez l'utiliser pour produire une fonction qui se comporte comme décrit dans votre question, au moins dans Bash:
Oublier de fournir un argument, ou fournir un argument non valide, produira un résultat de 1, donc
chance && do_stuff
ne sera jamaisdo_stuff
.Celui-ci utilise la formule générale pour «1 dans n » en utilisant
$RANDOM
, ce qui[[ $RANDOM -lt $((32767 / n + 1)) ]]
donne un (⎣32767 / n ⎦ + 1) dans 32768 chance. Les valeursn
qui ne sont pas des facteurs de 32768 introduisent un biais en raison de la répartition inégale dans la plage de valeurs possibles.la source
$((32767/parts+1))
supérieure à 1 ou nous courons le risque de voir le nombre de parties augmenter en 1 alors que le résultat de la division (et donc la limite) est le même. (suite)(32767/n-32767/(n+1))>=1
résolution de n qui donne une limite à ~ 181,5. En fait, le nombre de pièces pourrait atteindre 194 sans problème. Mais à 195 parties, la limite résultante est de 151, le même résultat qu'avec 194 parties. C'est incongru et devrait être évité. En bref, la limite supérieure pour le nombre de pièces (n), devrait être 194. Vous pouvez faire les tests de limite:[[ -z $1 || $1 -le 1 || $1 -ge 194 ]] && return 1
Solution non standard:
[ $(date +%1N) == 1 ] && do_stuff
Vérifiez si le dernier chiffre de l'heure actuelle en nanosecondes est 1!
la source
[ $(date +%1N) == 1 ] && do_stuff
ne se produit pas à intervalles réguliers, sinon le caractère aléatoire est gâché. Considérez-lewhile true; do [ $(date +1%N) == 1 ] && sleep 1; done
comme un contre-exemple abstrait. Néanmoins, l'idée de jouer avec les nanosecondes est vraiment bonne, je pense que je vais l'utiliser, donc +1clock_getres()
), 2) L'ordonnanceur n'est pas interdit, par exemple, de toujours démarrer une tranche de temps sur une limite de 100 nanosecondes (ce qui introduirait un biais même si l'horloge est correcte), 3) La méthode prise en charge pour obtenir des valeurs aléatoires est (généralement) de lire/dev/urandom
ou d'inspecter la valeur de$RANDOM
.Une alternative à l'utilisation
$RANDOM
est lashuf
commande:fera le travail. Également utile pour sélectionner au hasard des lignes dans un fichier, par exemple. pour une playlist de musique.
la source
Améliorer la première réponse et rendre beaucoup plus évident ce que vous essayez de réaliser:
la source
$RANDOM % 10
aura un biais, à moins que le$RANDOM
produit exactement un multiple de 10 valeurs différentes (ce qui ne se produit généralement pas dans un ordinateur binaire)"$RANDOM" -lt $((32767 / n + 1))
.Je ne sais pas si vous voulez du hasard ou de la périodicité ... Pour la périodicité:
Vous pouvez le mélanger avec l'astuce "$ RANDOM" ci-dessus pour produire quelque chose de plus chaotique, par exemple:
car je suis
seq 1 1000 $RANDOM
; faire écho $ i; faitHTH :-)
la source