Ejecuta comandos al azar

24

Quiero ejecutar uno de los dos comandos C1y C2al azar. ¿Cómo hago eso en la línea de comandos (bash)? Apreciará si una línea es posible.

usuario13107
fuente

Respuestas:

33
if (( RANDOM % 2 )); then C1; else C2; fi
Chris Down
fuente
1
Tenga en cuenta que si desea una probabilidad de 1 en N de ejecutar C1, probablemente deba usar en (( RANDOM % N == 0 ))lugar de (( RANDOM % N )). Es solo en el caso especial de N = 2 que tienen una probabilidad idéntica.
Acumenus
@ABB == 0está implícito en ((bloques sin comparación, por lo que no estoy seguro de lo que quieres decir.
Chris Down
@ABB == 0es un error tipográfico en mi comentario anterior, quiero decir, > 0está implícito. Dado % 100que casi siempre devolverá un valor anterior 0, eso se espera.
Chris Down
2
En pocas palabras, ¿ RANDOM % $Nsin qué uso práctico sería == 0? OMI, por ejemplo con N = 100, es mucho más pragmático querer una probabilidad de 1 en 100 (entregada con == 0) que una probabilidad de 99 en 100 (entregada sin == 0).
Acumenus
21

En tu caso especial:

C$((RANDOM%2+1))

funcionará :) Y oye, ¡es la respuesta más corta!

gniourf_gniourf
fuente
¿Por qué necesita dos conjuntos de paréntesis a su alrededor? Simplemente no estoy muy familiarizado con lo que haya usado.
AJMansfield
2
@AJMansfield $((1+1))-> 2, por ejemplo. $(( ))calcula lo que hay dentro.
Tyilo
3
Sería aún más corto si el OP eligiera C0 y C1. ¿Quizás no es un programador?
ott--
2
Estoy bastante seguro de que C1 y C2 eran marcadores de posición en lugar de comandos reales para ejecutar. :-)
Chris Down
Eso es lindo +1
sudo
5

Puedes hacer algo como esto en Bash:

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

Esto generará un número aleatorio, ya sea 0 o 1. Si es un 0, entonces C1 se ejecuta; de lo contrario, C2 se ejecuta si no lo es.

ejemplo

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

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

NOTA: El primer carácter $,, es el indicador.

otro ejemplo

Si le preocupa que C1 tenga que fallar para que C2 pueda ejecutarse, puede reestructurar lo anterior de la siguiente manera:

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

¿Por qué usar esto sobre una declaración if / then?

Esta respuesta ha sido criticada un poco, pero hay un método para mi locura. Aunque este patrón puede parecer más oscuro que un si / entonces, lo encuentro más legible y compacto cuando hago algo como lo siguiente:

#!/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

Referencias

slm
fuente
2
Esto se ejecutará C2si C1falla, lo que viola la especificación establecida en la pregunta (es decir, que solo se ejecuta uno de los comandos). x && y || zNo es equivalente a if x; then y; else z; fi.
Chris Down
@ChrisDown - ver mods.
slm
44
La edición nominalmente corrige esto, pero es realmente oscuro. "Si le preocupa que C1 tenga que fallar para que C2 pueda ejecutarse" no captura el escenario en absoluto. El problema es que si C1es un comando que a veces devuelve un código de salida distinto de cero, terminará ejecutando ambos C1y C2cuando eso suceda.
tripleee
+1 pero use en ((...))lugar de [...]- los paréntesis dobles son específicamente para expresiones aritméticas.
Glenn Jackman
@glennjackman: gracias, hice el cambio.
slm