Uruchamiaj polecenia losowo

24

Chcę uruchomić jedno z dwóch poleceń C1i C2losowo. Jak to zrobić w linii poleceń (bash)? Doceni, jeśli możliwy jest jednowarstwowy wkład.

użytkownik13107
źródło

Odpowiedzi:

33
if (( RANDOM % 2 )); then C1; else C2; fi
Chris Down
źródło
1
Pamiętaj, że jeśli chcesz 1 na N szansy na prowadzenie C1, prawdopodobnie (( RANDOM % N == 0 ))raczej musisz użyć zamiast (( RANDOM % N )). Tylko w wyjątkowym przypadku N = 2 prawdopodobieństwo jest identyczne.
Acumenus
@ABB == 0jest niejawne w ((blokach bez porównania, więc nie jestem pewien, co masz na myśli.
Chris Down
@ABB == 0to literówka w moim poprzednim komentarzu, to znaczy > 0niejawna. Ponieważ % 100prawie zawsze zwróci wartość powyżej 0, jest to oczekiwane.
Chris Down,
2
Po prostu umieścić, co praktyczne zastosowanie byłoby RANDOM % $Nbez == 0? IMO, na przykład przy N = 100, pragnienie pragnienia 1 na 100 (dostarczanego z == 0) jest znacznie bardziej pragmatyczne niż 99 na 100 (dostarczanego bez == 0).
Acumenus,
21

W twoim specjalnym przypadku:

C$((RANDOM%2+1))

zadziała :) Hej, to najkrótsza odpowiedź!

gniourf_gniourf
źródło
Dlaczego potrzebuje dwóch zestawów nawiasów wokół niego? Po prostu nie jestem zbyt dobrze zaznajomiony z tym, czego użyłeś.
AJMansfield
2
@AJMansfield $((1+1))-> 2, np. $(( ))oblicza, co jest w środku.
Tyilo
3
Byłoby jeszcze krócej, gdyby PO wybrał C0 i C1. Może nie jest programistą?
ott--
2
Jestem prawie pewien, że C1 i C2 były raczej symbolami zastępczymi niż rzeczywistymi poleceniami do uruchomienia. :-)
Chris Down
To słodkie. +1
sudo
5

Możesz zrobić coś takiego w Bash:

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

To wygeneruje liczbę losową, 0 lub 1. Jeśli jest to 0, wtedy C1 działa, w przeciwnym razie C2 działa, jeśli nie jest.

przykład

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

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

UWAGA: Pierwszy znak $, to znak zachęty.

inny przykład

Jeśli obawiasz się, że C1 musi zawieść, aby C2 mógł działać, możesz zrestrukturyzować powyższe w następujący sposób:

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

po co używać tego w instrukcji if / then?

Ta odpowiedź została trochę skrytykowana, ale w moim szaleństwie jest metoda. Chociaż ten wzór może wydawać się bardziej niejasny niż jeśli / to, uważam go za bardziej czytelny i zwarty, gdy wykonuję coś takiego:

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

Referencje

slm
źródło
2
Uruchomi się, C2jeśli C1zawiedzie, co narusza specyfikację przedstawioną w pytaniu (a mianowicie, że uruchamiana jest tylko jedna komenda). x && y || znie jest równoważne z if x; then y; else z; fi.
Chris Down
@ChrisDown - patrz mody.
slm
4
Edycja nominalnie to naprawia, ale jest to naprawdę niejasne. „Jeśli obawiasz się, że C1 musi ponieść porażkę, aby C2 mógł działać”, w ogóle nie wychwytuje scenariusza. Problem polega na tym, że jeśli C1jest to polecenie, które czasami zwraca niezerowy kod wyjścia, wykonasz oba C1i C2kiedy to się stanie.
tripleee
+1, ale używaj ((...))zamiast [...]- podwójne nawiasy są specyficzne dla wyrażeń arytmetycznych.
glenn jackman
@glennjackman - dzięki dokonałem zmiany.
slm