Befehle zufällig ausführen

24

Ich möchte einen der beiden Befehle ausführen C1und C2nach dem Zufallsprinzip. Wie mache ich das auf der Kommandozeile (bash)? Würde mich freuen, wenn ein Einzeiler möglich ist.

user13107
quelle

Antworten:

33
if (( RANDOM % 2 )); then C1; else C2; fi
Chris Down
quelle
1
Denken Sie daran, dass Sie, wenn Sie eine 1-in-N-Quote für das Ausführen von C1 möchten, wahrscheinlich (( RANDOM % N == 0 ))eher verwenden müssen als (( RANDOM % N )). Nur im Sonderfall von N = 2 haben diese die gleiche Wahrscheinlichkeit.
Acumenus
@ABB == 0ist implizit in ((Blöcken ohne Vergleich enthalten, daher bin ich mir nicht sicher, was du meinst.
Chris Down
@ABB == 0ist ein Tippfehler in meinem vorherigen Kommentar, ich meine, > 0ist implizit. Da % 100wird fast immer ein Wert über 0dem erwartet.
Chris Down
2
Einfach ausgedrückt, RANDOM % $Nohne welchen praktischen Nutzen == 0? IMO, zum Beispiel mit N = 100, ist es viel pragmatischer, eine Quote von 1 zu 100 (geliefert mit == 0) als eine Quote von 99 zu 100 (geliefert ohne == 0) zu wollen.
Acumenus
21

In Ihrem speziellen Fall:

C$((RANDOM%2+1))

wird funktionieren :) Und hey, es ist die kürzeste Antwort!

gniourf_gniourf
quelle
Warum braucht es zwei Klammern? Ich bin nur nicht sehr vertraut mit dem, was du benutzt hast.
AJMansfield
2
@AJMansfield $((1+1))-> 2, zB. $(( ))berechnet was drin ist.
Tyilo
3
Es wäre noch kürzer, wenn das OP C0 und C1 wählen würde. Vielleicht ist er kein Programmierer?
ott--
2
Ich bin mir ziemlich sicher, dass C1 und C2 Platzhalter und keine eigentlichen auszuführenden Befehle waren. :-)
Chris Down
Das ist süß. +1
sudo
5

In Bash können Sie so etwas tun:

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

Dies erzeugt eine Zufallszahl, entweder 0 oder 1. Wenn es eine 0 ist, wird C1 ausgeführt, andernfalls wird C2 ausgeführt, wenn dies nicht der Fall ist.

Beispiel

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

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

HINWEIS: Das erste Zeichen $ist die Eingabeaufforderung.

ein anderes Beispiel

Wenn Sie befürchten, dass C1 ausfallen muss, damit C2 ausgeführt werden kann, können Sie die obigen Schritte folgendermaßen umstrukturieren:

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

Warum sollte dies über einer if / then-Anweisung verwendet werden?

Diese Antwort wurde ein wenig kritisiert, aber es gibt eine Methode für meinen Wahnsinn. Obwohl dieses Muster dunkler erscheinen mag als ein Wenn / Dann finde ich es lesbarer und kompakter, wenn ich etwas wie das Folgende tue:

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

Verweise

slm
quelle
2
Dies wird ausgeführt, C2wenn ein C1Fehler auftritt, was gegen die in der Frage angegebene Spezifikation verstößt (nämlich, dass nur einer der Befehle ausgeführt wird). x && y || zist nicht gleichbedeutend mit if x; then y; else z; fi.
Chris Down
@ ChrisDown - siehe Mods.
SLM
4
Die Bearbeitung behebt dies nominell, aber es ist wirklich dunkel. "Wenn Sie befürchten, dass C1 ausfallen muss, damit C2 ausgeführt werden kann", wird das Szenario überhaupt nicht erfasst. Das Problem ist, dass wenn C1es sich um einen Befehl handelt, der manchmal einen Exit-Code ungleich Null zurückgibt, Sie am Ende beide ausführen C1und C2wenn dies passiert.
Tripleee
+1, aber verwenden Sie ((...))statt [...]- doppelte Klammern sind speziell für arithmetische Ausdrücke.
Glenn Jackman
@glennjackman - danke, ich habe die Änderung vorgenommen.
SLM