Exécuter des commandes au hasard

24

Je veux exécuter l'une des deux commandes C1et C2au hasard. Comment faire cela en ligne de commande (bash)? Appréciera si un seul revêtement est possible.

user13107
la source

Réponses:

33
if (( RANDOM % 2 )); then C1; else C2; fi
Chris Down
la source
1
Gardez à l'esprit que si vous voulez une cote de 1 sur N pour exécuter C1, vous devez probablement utiliser (( RANDOM % N == 0 ))plutôt que (( RANDOM % N )). Ce n'est que dans le cas particulier de N = 2 que ceux-ci ont une probabilité identique.
Acumenus
@ABB == 0est implicite dans les ((blocs sans comparaison, donc je ne sais pas ce que vous voulez dire.
Chris Down
@ABB == 0est une faute de frappe dans mon commentaire précédent, je veux dire > 0est implicite. Puisque % 100renverra presque toujours une valeur au 0- dessus , cela est attendu.
Chris Down
2
Autrement dit, de quelle utilité pratique serait RANDOM % $Nsans == 0? OMI, par exemple avec N = 100, il est beaucoup plus pragmatique de vouloir une cote de 1 sur 100 (livré avec == 0) qu'une cote de 99 sur 100 (livré sans == 0).
Acumenus
21

Dans votre cas particulier:

C$((RANDOM%2+1))

fonctionnera :) Et bon, c'est la réponse la plus courte!

gniourf_gniourf
la source
Pourquoi a-t-il besoin de deux jeux de parenthèses autour de lui? Je ne connais pas très bien ce que vous avez utilisé.
AJMansfield
2
@AJMansfield $((1+1))-> 2, par exemple. $(( ))calcule ce qu'il y a à l'intérieur.
Tyilo
3
Il serait encore plus court si l'OP choisissait C0 et C1. Peut-être qu'il n'est pas programmeur?
ott--
2
Je suis assez sûr que C1 et C2 étaient des espaces réservés plutôt que des commandes réelles à exécuter. :-)
Chris Down
C'est mignon. +1
sudo
5

Vous pouvez faire quelque chose comme ça dans Bash:

$ (( RANDOM%2 == 0 )) && C1 || C2

Cela générera un nombre aléatoire, soit 0 ou 1. Si c'est un 0, alors C1 s'exécute, sinon C2 s'exécute s'il ne l'est pas.

Exemple

$ (( RANDOM%2 == 0 )) && echo 0 || echo 1
1

$ (( RANDOM%2 == 0 )) && echo 0 || echo 1
0

REMARQUE: le premier caractère $, est l'invite.

un autre exemple

Si vous craignez que C1 doive échouer pour que C2 puisse fonctionner, vous pouvez restructurer ce qui précède comme suit:

(( RANDOM%2 == 0 )) && CMD=C1 || CMD=C2
$CMD

pourquoi utiliser ceci sur une instruction if / then?

Cette réponse a été un peu critiquée mais il y a une méthode à ma folie. Bien que ce modèle puisse sembler plus obscur qu'un si / alors je le trouve plus lisible et compact lorsque vous faites quelque chose comme ceci:

#!/bin/bash
CMD=""
DIRS="/etc /home /www /data1 /data2 /var/log /var/spool/mail"
FILE="/backup/$(hostname)-$(date +'%m-%d-%y').tar.gz"
[ "$1" == "nas" ]  && CMD="lftp -u user,password -e 'cd /dump/; mput /backup/*; quit' nas.mylan.com" || :
[ "$1" == "scp" ]  && CMD="scp /backup/* scponly@dumpserver:incoming' username" || :
[ "$1" == "tape" ] && CMD='tar -cf /dev/st0 /backup/*' || :
[ "$CMD" == "" ]   && exit 1 || :
# make a backup
tar -zcvf  $FILE $DIRS
# Now depend upon circumstances run a backup command
$CMD

Les références

slm
la source
2
Cela fonctionnera C2si C1échoue, ce qui constitue une violation aux exigences définies dans la question ( à savoir que seule une des commandes est exécuté). x && y || zn'est pas équivalent à if x; then y; else z; fi.
Chris Down
@ChrisDown - voir les mods.
slm
4
L'édition corrige nominalement cela, mais c'est vraiment obscur. "Si vous êtes préoccupé par le fait que C1 doive échouer pour que C2 puisse s'exécuter" ne capture pas du tout le scénario. Le problème est que si C1est une commande qui renvoie parfois un code de sortie non nul, vous finirez par exécuter les deux C1et C2quand cela se produira .
tripleee
+1 mais utilisez ((...))au lieu de [...]- les parenthèses doubles sont spécifiquement destinées aux expressions arithmétiques.
glenn jackman
@glennjackman - merci d'avoir fait le changement.
slm