- Bash स्क्रिप्ट में वेब सर्वर की स्थिति जांचने के लिए बार-बार कनेक्शन प्रयास करने पर सर्वर अप्रत्याशित रूप से अनंत लूप में फंस सकता है
- इसे हल करने के लिए इस्तेमाल होने वाला टूल
timeout कमांड के चलने की समय-सीमा तय करता है, और सीमा पार होने पर सिग्नल भेजकर प्रोसेस समाप्त करने की कोशिश करता है
until जैसे shell built-in पर इसे सीधे लागू नहीं किया जा सकता, इसलिए bash प्रोसेस रैपिंग या स्क्रिप्ट को अलग करने के जरिए इसे हल किया जा सकता है
Bash स्क्रिप्ट में वेब सर्वर का इंतज़ार और अनंत लूप की समस्या
- व्यवहारिक कामों में Bash स्क्रिप्ट का उपयोग करके वेब सर्वर सेटअप और स्टेटस चेक किया जाता है
- संरचना ऐसी होती है कि सर्वर चालू होने तक अगला काम रोका जाता है, और सामान्यतः यह बिना समस्या के काम करती है
- लेकिन सर्वर शुरू होते समय क्रैश हो जाए तो यह अनंत लूप में फंस सकता है, इसलिए समाधान की ज़रूरत पड़ती है
until के उपयोग का उदाहरण और उसकी सीमा
timeout utility का परिचय
timeout कमांड किसी कमांड के तय समय के भीतर पूरा न होने पर सिग्नल (SIGTERM आदि) भेजकर उसे समाप्त करता है
- उदाहरण:
timeout 1s sleep 5 में 1 सेकंड बाद sleep प्रोसेस को समाप्त करने की कोशिश की जाती है
- समाप्ति पर यह असामान्य exit code (जैसे 124) लौटाता है
timeout और until को साथ उपयोग करने की कोशिश और समस्या
समाधान: Bash प्रोसेस रैपिंग या बाहरी स्क्रिप्ट का उपयोग
1 टिप्पणियां
Hacker News राय
मेरी सबसे पसंदीदा कम-ज्ञात ट्रिक्स में से एक है
stracefault injection का उपयोग करके अलग-अलग system call failures को टेस्ट करने का तरीकासंबंधित लिंक में इसका और विस्तृत विवरण दिया गया है
यह फीचर वाकई कमाल का लगता है, और काश यह पहले से पता होता, ऐसा अनुभव साझा किया
failure branch को टेस्ट करने का तरीका नहीं होने पर वे अक्सर function के कुछ हिस्सों को अस्थायी कोड से बदल देते थे, लेकिन इस ट्रिक से अधिक संक्षिप्त तरीका संभव लगता है
राय है कि यह तरीका सच में बहुत उपयोगी लगता है
साथ ही यह जिज्ञासा जताई कि क्या Windows में भी ऐसा कोई समान फीचर है
service health check में सबसे अच्छा तरीका यह है कि maximum timeout duration और maximum retry count दोनों सेट किए जाएँ
आम तौर पर X बार तक retry किया जाता है, और अधिकतम Y समय के भीतर failure मान लिया जाता है
बहुत देर तक इंतज़ार करने के बजाय जितना जल्दी हो सके failure तय करने की ज़रूरत पर ज़ोर
standard services में container dependencies पर्याप्त रूप से सुनिश्चित होने और ready होने के बाद ही health check शुरू करना चाहिए
Kubernetes में Init Container, AWS ECS में
dependsOn, Docker Compose मेंdepends_onसेटिंग का संदर्भ दिया गयाPOSIX shell script का उदाहरण दिया गया
लेकिन यह भी कहा गया कि
curlमें यह फीचर पहले से built-in है, इसलिए अलग script के बिना इसे इस तरह इस्तेमाल किया जा सकता हैMac पर
timeoutकमांड डिफ़ॉल्ट रूप से उपलब्ध नहीं होती, इसलिए केवल bash builtins से timeout लागू करने की कई कोशिशें करने का अनुभव साझा कियायह समझाया कि
sleepकमांड POSIX में standard है, इसलिए उसका उपयोग किया जा सकता हैनीचे timeout फीचर लागू करने का उदाहरण दिया गया
times_upनाम की function से timeout handle किया गया10 सेकंड timeout के साथ
forloop को 20 बार चलाकर टेस्ट करने का उदाहरण दिया गया12 साल पहले Stack Overflow की सलाह के आधार पर ऐसा ही तरीका लागू करने का अनुभव साझा किया
संदर्भ लिंक में विस्तृत जानकारी देखी जा सकती है
ज़ोर दिया गया कि इसमें केवल shell builtins और
sleepका उपयोग हुआ था, और वह कोड POSIX-compatible होना अनिवार्य थायह भी बताया गया कि उदाहरण में bash का
{1..20}syntax POSIX नहीं है, इसलिए सावधानी ज़रूरी हैमेरा सुधार यह था कि timeout न होने पर
trueऔर timeout होने परfalseलौटे, ताकि script में error handling आसान हो सकेनीचे की तरह command और
sleepको parallel चलाकर, तय समय बीतने पर signal से command को बंद करने का बहुत सरल तरीका साझा किया गया13 साल पहले
read -tका उपयोग करके timeout लागू करने वाली script का उदाहरण साझा किया गयालिंक
curlमें पहले से--retry-connrefusedफ्लैग मौजूद है, इसलिए shell loop के बिना भी इस फीचर का सीधा उपयोग किया जा सकता हैbash -cका उपयोग करते समय अगर variables पास करने हों, तो नीचे की तरह arguments जोड़ने की सलाह दी गई"--"का उपयोग क्यों किया जाता है औरargv[0]की क्या भूमिका है, यह समझाया गयायह भी कहा गया कि
printf %qका उपयोग किया जा सकता है, लेकिन Bourne-compatible तरीका अधिक पसंद हैसमझाया गया कि
"--"का मतलब bash और अधिकांश Unix/Linux CLI में option termination signal के रूप में बहुत स्पष्ट हैसंबंधित संदर्भ
साझा किया गया कि Busybox
argv[0]के मान के आधार पर चलाए जाने वाले program का निर्णय करता है, इसलिए इसे"ls","mv","cp"जैसे इच्छित command के रूप में सेट किया जा सकता हैजब retry logic की ज़रूरत होती है, तो मैं आम तौर पर नीचे जैसा तरीका इस्तेमाल करता हूँ
यह बहुत polished नहीं है, लेकिन आम तौर पर सही काम करता है, और अगला उन्नत कदम exponential backoff लागू करना हो सकता है
scalability के लिहाज़ से भी इसका फायदा है
shellcheck इस स्थिति में
_variable का उपयोग करके इसे संभालने की सलाह देता हैसंदर्भ लिंक
इस बात पर ज़ोर दिया गया कि
eventually_succeedsfunction को स्थिति के अनुसार timeout या अतिरिक्त defensive coding की ज़रूरत पड़ सकती हैPOSIX/process/IO में हमेशा defensive code लिखने की ज़रूरत याद दिलाई गई
अतीत में जब बच्चे छोटे थे, तब 30 मिनट तक केवल एक प्रोग्राम देखने की अनुमति देने के लिए नीचे दिए गए command को एक तरह के parental control tool की तरह इस्तेमाल करने का अनुभव साझा किया गया
इसे बहुत उपयोगी आइडिया बताया गया
यह बताया गया कि subprocess को signal भेजना पड़ता है, इसलिए command inline या temporary script file का उपयोग ज़्यादा पसंद नहीं है
मेरी पसंदीदा विधि यह है कि ज़रूरी complex logic को एक function में लिखा जाए, उसे export किया जाए, और फिर
timeout bash -cसे wrap किया जाएयह aidenn0 द्वारा बताई गई safe argument passing विधि से जुड़ा है
"$@"ज़रूर लिखना चाहिएनहीं तो spaces वाले arguments सही तरह से pass नहीं होंगे
इसे जाँचने के लिए
long_fnका उदाहरण भी साझा किया गयापहले
timeoutपर लिखी गई एक blog post का ज़िक्र किया गयाअगर shell के बजाय सामान्य programming language या अंदरूनी कार्यप्रणाली में अधिक रुचि हो, तो संबंधित ब्लॉग देखने की सलाह दी गई
Kubernetes setup में command timeout जोड़ने का अनुभव साझा किया गया
await-cmd.sh,await-http.sh,await-tcp.shजैसी POSIX shell scripts परिपक्व हैं और कुछ स्थितियों में काफ़ी उपयोगी हो सकती हैंसंबंधित project लिंक