Bash में N समय से 1 कमांड कैसे चलाएं


15

मुझे यादृच्छिक रूप से कमांड चलाने का एक तरीका चाहिए, 10 में से 1 बार कहें। क्या ऐसा करने के लिए एक अंतर्निहित या जीएनयू कोरुटिल है, आदर्श रूप से कुछ इस तरह:

chance 10 && do_stuff

जहां do_stuffकेवल 10 बार में 1 निष्पादित किया गया है? मुझे पता है कि मैं एक पटकथा लिख ​​सकता था, लेकिन यह काफी सरल बात लगती है और मैं सोच रहा था कि क्या कोई परिभाषित तरीका है।


1
यह एक काफी अच्छा संकेतक है कि आपकी स्क्रिप्ट संभवतः वाजिब विकल्प को जारी रखने के लिए बैश के लिए हाथ से बाहर हो रही है। आपको अधिक पूर्ण विकसित प्रोग्रामिंग भाषा पर विचार करना चाहिए, शायद पायथन या रूबी जैसी स्क्रिप्टिंग भाषा।
अलेक्जेंडर -

@Alexander यह वास्तव में एक स्क्रिप्ट भी नहीं है, सिर्फ एक लाइन। मैं इसे एक क्रॉन-जॉब में उपयोग कर रहा हूं ताकि मुझे हर बार बेतरतीब ढंग से सूचित किया जा सके और कुछ करने के लिए एक अनुस्मारक के रूप में
13

जवाबों:


40

में ksh, बैश, Zsh, यश या बिजीबॉक्स sh:

[ "$RANDOM" -lt 3277 ] && do_stuff

RANDOMतो ऊपर (के पास) एक एक-इन-दस मौका देता कॉर्न, बैश, यश, जेड और बिजीबॉक्स गोले की विशेष चर, 0 और 32767 हर बार यह मूल्यांकन किया जाता है जो छद्म यादृच्छिक दशमलव पूर्णांक मान पैदा करता है।

आप इसका उपयोग एक ऐसे समारोह का निर्माण करने के लिए कर सकते हैं जो आपके प्रश्न में वर्णित है, कम से कम बैश में:

function chance {
  [[ -z $1 || $1 -le 0 ]] && return 1
  [[ $RANDOM -lt $((32767 / $1 + 1)) ]]
}

तर्क प्रदान करना भूल जाना, या अमान्य तर्क प्रदान करना, 1 का परिणाम chance && do_stuffदेगा , इसलिए कभी नहीं do_stuff

यह "1 इन एन " के लिए सामान्य सूत्र का उपयोग करता है $RANDOM, जो कि [[ $RANDOM -lt $((32767 / n + 1)) ]], 32768 मौका में (6732767 / n 32 + 1) दे रहा है । मान nजिनमें से 32768 के कारक नहीं हैं, संभावित मानों की श्रेणी में असमान विभाजन के कारण पूर्वाग्रह का परिचय देते हैं।


(१/२) इस मुद्दे पर फिर से आने पर: यह सहज है कि भागों की संख्या पर ऊपरी सीमा होनी चाहिए, उदाहरण के लिए, ४०.०० भागों का होना संभव नहीं है। वास्तव में वास्तविक सीमा काफी छोटी है। मुद्दा यह है कि पूर्णांक विभाजन सिर्फ एक अनुमान है कि प्रत्येक भाग कितना बड़ा हो सकता है। यह आवश्यक है कि सीमा के अंतर में दो लगातार भागों का परिणाम $((32767/parts+1))1 से अधिक हो या हम 1 में भागों की संख्या में वृद्धि होने के जोखिम में भाग लें, जबकि विभाजन (और इसलिए सीमा) का परिणाम समान हो। (cont ..)
इसहाक

(2/2) (cont ..) वास्तव में उपलब्ध की तुलना में अधिक संख्या के लिए जिम्मेदार होगा। इसके लिए सूत्र (32767/n-32767/(n+1))>=1, n के लिए हल है जो ~ 181.5 पर एक सीमा देता है। वास्तव में भागों की संख्या बिना मुद्दे के 194 तक चल सकती है। लेकिन 195 भागों में, परिणामी सीमा 151 है, 194 भागों के समान परिणाम। यह असंगत है और इससे बचा जाना चाहिए। संक्षेप में, भागों की संख्या के लिए ऊपरी सीमा (n), 194 होनी चाहिए। आप सीमा परीक्षण कर सकते हैं:[[ -z $1 || $1 -le 1 || $1 -ge 194 ]] && return 1
इसहाक

25

गैर-मानक समाधान:

[ $(date +%1N) == 1 ] && do_stuff

जांचें कि क्या नैनोसेकंड में वर्तमान समय का अंतिम अंक 1 है!


वह तो कमाल है।
एरिक ड्यूमिनिल

2
आपको यह सुनिश्चित करना होगा कि कॉल [ $(date +%1N) == 1 ] && do_stuffनियमित अंतराल पर न हो, अन्यथा यादृच्छिकता खराब हो जाती है। while true; do [ $(date +1%N) == 1 ] && sleep 1; doneएक अमूर्त प्रतिरूप के रूप में सोचो । फिर भी, नैनोसेकंड के साथ खेलने का विचार वास्तव में अच्छा है, मुझे लगता है कि मैं इसका उपयोग करूंगा, इसलिए +1
XavierStuvw

3
@XavierStuvw मुझे लगता है कि यदि कोड सेकंड की जाँच कर रहा था तो आपके पास एक बिंदु होगा। लेकिन नैनोसेकंड? यह वास्तव में यादृच्छिक दिखाई देना चाहिए।
एरिक डुमिनील

9
@EricDuminil: दुर्भाग्यवश: 1) सिस्टम घड़ी वास्तविक नैनोसेकंड रिज़ॉल्यूशन प्रदान करने के लिए अनुबंधित नहीं है (यह निकटतम हो सकता है clock_getres()), 2) शेड्यूलर से निषिद्ध नहीं है, उदाहरण के लिए, हमेशा 100-नैनोसेकंड सीमा पर एक टाइमलाइन शुरू करना (जो घड़ी के सही होने पर भी पूर्वाग्रह का परिचय देगा), 3) यादृच्छिक मूल्यों को प्राप्त करने का समर्थित तरीका (आमतौर पर) /dev/urandomके मूल्य से पढ़ना या निरीक्षण करना है $RANDOM
केविन

1
@ केविन: टिप्पणी के लिए बहुत बहुत धन्यवाद।
एरिक डुमिनील

21

उपयोग का एक विकल्प $RANDOMहै shufआदेश:

[[ $(shuf -i 1-10 -n 1) == 1 ]] && do_stuff

नौकरी करेंगे। किसी फ़ाइल से लाइनों को बेतरतीब ढंग से चुनने के लिए भी उपयोगी है, जैसे। एक संगीत प्लेलिस्ट के लिए।


1
उस आदेश को नहीं जानता था। बहुत अच्छा!
Eisenknurr

12

पहले उत्तर में सुधार करना और इसे और अधिक स्पष्ट करना कि आप क्या हासिल करने की कोशिश कर रहे हैं:

[ $(( $RANDOM % 10 )) == 0 ] && echo "You win" || echo "You lose"

1
$RANDOM % 10एक पूर्वाग्रह होगा, जब तक कि $RANDOMवास्तव में 10 विभिन्न मूल्यों (जो आम तौर पर एक द्विआधारी कंप्यूटर में नहीं होता है) के कई गुण पैदा करता है
phuclv

1
@ एफ्यूक्लेव हाँ, इसमें वैसा ही पूर्वाग्रह होगा "$RANDOM" -lt $((32767 / n + 1))
Eisenknurr

हां, पूर्वाग्रह 1-इन -10 के लिए 0.1 के बजाय 0.100006104 (जब 0 के खिलाफ जांच कर रहा है) समान है।
स्टीफन किट

1

मुझे यकीन नहीं है कि आप यादृच्छिकता या आवधिकता चाहते हैं ... आवधिकता के लिए:

for i in `seq 1 10 100`; do echo $i;done
1
11
21
31
41
51
61
71
81
91

उदाहरण के लिए, कुछ और अराजक उत्पन्न करने के लिए आप इसे "$ RANDOM" चाल के साथ मिला सकते हैं:

में मैं के लिए seq 1 1000 $RANDOM; $ गूंज करो; मैंने किया

HTH :-)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.