เรียกใช้คำสั่งแบบสุ่ม


24

ฉันต้องการเรียกใช้หนึ่งในสองคำสั่งC1และC2โดยการสุ่ม ฉันจะทำเช่นนั้นใน commandline (bash) ได้อย่างไร จะซาบซึ้งถ้าเป็นไปได้หนึ่งซับ

คำตอบ:


33
if (( RANDOM % 2 )); then C1; else C2; fi

1
จำไว้ว่าถ้าคุณต้องการที่ 1 ในอัตราต่อรองของการทำงาน N C1 คุณอาจต้องใช้มากกว่า(( RANDOM % N == 0 )) (( RANDOM % N ))มันเป็นกรณีพิเศษของ N = 2 เท่านั้นที่มีความน่าจะเป็นเหมือนกัน
คิวเมนตัส

@ABB == 0มีความหมายใน((บล็อกโดยไม่มีการเปรียบเทียบดังนั้นฉันไม่แน่ใจว่าคุณหมายถึงอะไร
Chris Down

@ABB == 0เป็นตัวพิมพ์ผิดในความคิดเห็นก่อนหน้าของฉันฉันหมายถึง> 0เป็นนัย เนื่องจาก% 100จะส่งคืนค่าข้างต้นเกือบทุก0ครั้งนั่นเป็นสิ่งที่คาดไว้
Chris Down

2
ชัดถ้อยชัดคำใส่ของสิ่งที่ใช้งานจริงจะเป็นRANDOM % $Nโดยไม่== 0? IMO เช่นที่มี N = 100 มันเป็นวิธีปฏิบัติที่ดีกว่าหากต้องการอัตรา 1 ใน 100 (ส่งโดยมี== 0) มากกว่า 99 ใน 100 อัตราต่อรอง (ส่งโดยไม่มี== 0)
คิวเมนตัส

21

ในกรณีพิเศษของคุณ:

C$((RANDOM%2+1))

จะทำงาน :) และเฮ้มันเป็นคำตอบที่สั้นที่สุด!


เหตุใดจึงต้องใช้วงเล็บสองชุดล้อมรอบ ฉันไม่คุ้นเคยกับสิ่งที่คุณใช้
AJMansfield

2
@AJMansfield $((1+1))-> 2เช่น $(( ))คำนวณสิ่งที่อยู่ภายใน
Tyilo

3
มันจะยิ่งสั้นลงถ้า OP เลือก C0 และ C1 บางทีเขาอาจไม่ใช่โปรแกรมเมอร์
ott--

2
ฉันค่อนข้างแน่ใจว่า C1 และ C2 เป็นตัวยึดตำแหน่งแทนที่จะเรียกใช้คำสั่งจริง :-)
Chris Down

นั้นน่ารัก. +1
sudo

5

คุณสามารถทำสิ่งนี้ใน Bash:

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

สิ่งนี้จะสร้างตัวเลขสุ่มทั้ง 0 หรือ 1 หากเป็น 0 ดังนั้นจะมี C1 เรียกใช้มิฉะนั้น C2 จะเรียกใช้หากไม่เป็นเช่นนั้น

ตัวอย่าง

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

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

หมายเหตุ: ตัวอักษรตัวแรก$, เป็นพรอมต์

ตัวอย่างอื่น

หากคุณกังวลว่า C1 จะต้องล้มเหลวเพื่อให้ C2 สามารถทำงานคุณสามารถปรับโครงสร้างด้านบนดังนี้:

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

เหตุใดจึงใช้สิ่งนี้เหนือคำสั่ง if / then?

คำตอบนี้ได้รับการวิพากษ์วิจารณ์เล็กน้อย แต่มีวิธีการบ้าของฉัน แม้ว่ารูปแบบนี้อาจดูคลุมเครือกว่าถ้า / จากนั้นฉันพบว่าสามารถอ่านได้และมีขนาดกะทัดรัดกว่าเมื่อทำสิ่งต่อไปนี้:

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

อ้างอิง


2
นี้จะทำงานC2ถ้าC1ล้มเหลวที่ละเมิดข้อกำหนดออกมาวางในคำถาม (คือว่ามีเพียงหนึ่งของคำสั่งที่มีการเรียกใช้) จะไม่เทียบเท่ากับx && y || z if x; then y; else z; fi
Chris Down

@ChrisDown - ดู mods
slm

4
การแก้ไขนี้แก้ไขสิ่งที่มีชื่อ แต่ไม่ชัดเจน "หากคุณกังวลว่า C1 ต้องล้มเหลวเพื่อให้ C2 สามารถทำงานได้" จะไม่จับภาพสถานการณ์เลย ปัญหาคือว่าถ้าC1เป็นคำสั่งซึ่งบางครั้งส่งคืนโค้ดออกที่ไม่เป็นศูนย์คุณจะสิ้นสุดการดำเนินการทั้งสองC1และC2เมื่อเกิดขึ้น
tripleee

+1 แต่ใช้((...))แทน[...]- วงเล็บคู่นั้นมีไว้สำหรับนิพจน์ทางคณิตศาสตร์โดยเฉพาะ
เกล็นแจ็คแมน

@glennjackman - ขอบคุณฉันได้ทำการเปลี่ยนแปลงแล้ว
slm
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.