पायथन लिपि को स्वचालित रूप से फिर से कैसे शुरू किया जाए अगर यह मारा जाता है या मर जाता है


31

मैं अपनी उबंटू मशीन (12.04) में पृष्ठभूमि में अपनी पायथन स्क्रिप्ट इस तरह से चला रहा हूं -

nohup python testing.py > test.out &

अब, यह संभव हो सकता है कि किसी भी स्तर पर मेरे ऊपर Python scriptजो भी कारण के लिए मर सकता है।

इसलिए मैं सोच रहा हूँ कि cron agentबैश शेल लिपि में कुछ ऐसा हो जो मेरे उपरोक्त पायथन लिपि को स्वचालित रूप से फिर से शुरू कर सके, अगर यह किसी भी कारण से मार दिया जाए।

क्या ऐसा करना संभव है? यदि हाँ, तो इस तरह की समस्या को हल करने का सबसे अच्छा तरीका क्या है?

अद्यतन करें:

testing.confफाइल को इस तरह बनाने के बाद -

chdir /tekooz
exec python testing.py
respawn

मैं इसे शुरू करने के लिए sudo कमांड से नीचे भागा, लेकिन मैं ps ax का उपयोग करके उस प्रक्रिया को नहीं देख सकता?

root@bx13:/bezook# sudo start testing
testing start/running, process 27794
root@bx13:/bezook# ps ax | grep testing.py
27806 pts/3    S+     0:00 grep --color=auto testing.py

किसी भी विचार क्यों px कुल्हाड़ी मुझे कुछ भी नहीं दिखा रहा है? और मैं कैसे जांचूं कि मेरा कार्यक्रम चल रहा है या नहीं?

यह मेरी अजगर की स्क्रिप्ट है -

#!/usr/bin/python
while True:
    print "Hello World"
    time.sleep(5)

जवाबों:


24

उबंटू पर (14.04, 16.04 तक और बाद में सिस्टमड का उपयोग) एक क्रॉन जॉब की तुलना में बेहतर करने के लिए अपस्टार्ट का उपयोग कर सकता है। आप एक कॉन्फ़िगर सेटअप में डालते हैं /etc/initऔर सुनिश्चित करते हैं कि आप रिस्पांस निर्दिष्ट करें

यह एक न्यूनतम फ़ाइल हो सकती है /etc/init/testing.conf(जैसा कि संपादित करें root):

chdir /your/base/directory
exec python testing.py
respawn

और आप के साथ परीक्षण कर सकते हैं /your/base/directory/testing.py:

from __future__ import print_function

import time

with open('/var/tmp/testing.log', 'a') as fp:
    print(time.time(), 'done', file=fp)
    time.sleep(3)

और इसके साथ शुरू करें:

sudo start testing

और जो होता है उसका अनुसरण करें (दूसरी विंडो में):

tail -f /var/tmp/testing.log

और इसके साथ रुकें:

sudo stop testing

आप [start on][2]सिस्टम के बूट पर कमांड शुरू करने के लिए भी जोड़ सकते हैं ।


यदि आप क्रॉन जॉब का उपयोग करते हैं तो आप पीआईडी ​​फाइल हैंडलिंग के लिए या तो लागू करना चाहते हैं या कुछ कोड ढूंढना चाहते हैं। आप चाहते हैं कि आपकी सेवा / स्क्रिप्ट / डेमॉन एक PID फ़ाइल (पारंपरिक रूप से / var / run के तहत स्थित) बनाएँ और इसकी स्टार्ट-अप कोड जाँच करें कि क्या फ़ाइल सामग्री बासी है (किसी मारे गए प्रक्रिया द्वारा छोड़ दी गई है)। इस तरह का कोड आश्चर्यजनक रूप से दौड़ और कोने के मामलों में मुफ्त लिखना मुश्किल है। stackoverflow.com/questions/788411/…
जिम डेनिस

@Zelda: सुझाव के लिए धन्यवाद .. मैं लिनक्स / यूनिक्स की दुनिया में नया हूँ .. /etc/initफ़ाइल में मुझे किस प्रकार के बदलाव करने हैं ? यदि आप मेरे लिए कदम से कदम गाइड प्रदान कर सकते हैं, तो मैं कुछ सीखने और सही काम करने में सक्षम हो
शस्त्रागार

@ जबाव मैंने जवाब को और पूरा कर दिया। यदि आप आउटपुट के लिए फाइल नहीं खोलना चाहते हैं और अपने प्रिंट स्टेटमेंट को फिर से लिखना चाहते हैं तो आप sys.stdout = open(file_name, 'w')शुरुआत में कुछ कर सकते हैं ।
ज़ेल्डा

थैंक यू ज़ेल्डा। आपकी मदद की सराहना की .. मैंने कुछ विवरणों के साथ प्रश्न को अद्यतन किया .. मैं यह देखने के लिए ऐसा करने की कोशिश कर रहा हूं कि मेरा टेस्टिंगहोम चल रहा है या नहीं .. यह मुझे नहीं दिखाता है कि यह चल रहा है या नहीं px ax | grep testing.py.. यह मुझे कुछ नहीं लौटा रहा है? कोई विचार क्यों?
शस्त्रागार

आपको क्लॉज़ को छोड़कर पूरी चीज़ को एक प्रयास में रखना चाहिए या लॉगफ़ाइल को लिखना चाहिए कि क्या अपवाद उत्पन्न हुआ था और यह कि प्रोग्राम से बाहर निकल गया। हो सकता है कि प्रिंट स्टेटमेंट काम न करे क्योंकि यह स्टैडआउट को नहीं लिख सकता है।
ज़ेल्डा

20

आप अधिक शेल उन्मुख दृष्टिकोण भी ले सकते हैं। cronअपने स्क्रिप्ट के लिए अपने देखो और अगर यह मर जाता है यह relaunch।

  1. रनिंग करके एक नया कॉन्टैब बनाएं crontab -e। यह आपके पसंदीदा टेक्स्ट एडिटर की एक विंडो लाएगा।

  2. इस लाइन को उस फ़ाइल में जोड़ें जो अभी खुली है

    */5 * * * * pgrep -f testing.py || nohup python /home/you/scripts/testing.py > test.out
  3. फ़ाइल सहेजें और संपादक से बाहर निकलें।

आपने बस एक नया बनाया है crontabजो हर 5 मिनट में चलाया जाएगा और जब तक यह पहले से ही चल रहा है तब तक अपनी स्क्रिप्ट लॉन्च करें। पर एक अच्छा सा ट्यूटोरियल के लिए यहाँ देखें cron। आधिकारिक उबंटू डॉक्स पर cronकर रहे हैं यहाँ

वास्तविक कमांड चलाया जा रहा है pgrepजो कमांड लाइन में दिए गए स्ट्रिंग के लिए चल रही प्रक्रियाओं को खोजता है। pgrep fooनामक एक कार्यक्रम की खोज करेगा fooऔर अपनी प्रक्रिया पहचानकर्ता को लौटाएगा । pgrep -fयह प्रोग्राम को लॉन्च करने के लिए उपयोग की जाने वाली पूरी कमांड लाइन को खोजता है और न केवल प्रोग्राम का नाम (उपयोगी है क्योंकि यह एक पायथन स्क्रिप्ट है)।

||प्रतीक का अर्थ है "अगर पिछला आदेश में विफल रहा है ऐसा करने के"। इसलिए, यदि आपकी स्क्रिप्ट नहीं चल रही है, तो pgrepवसीयत विफल हो जाएगी क्योंकि यह कुछ भी नहीं पाएगी और आपकी स्क्रिप्ट लॉन्च की जाएगी।


धन्यवाद .. लेकिन मैं linux और unix में नया हूँ इसलिए पता नहीं है कि crontab कहाँ है? क्या यह कहीं मेरे ubuntu मशीन में एक फ़ाइल है?
शस्त्रागार

@Webby अद्यतन जवाब देखें।
terdon

धन्यवाद टेराडॉन .. मैं इस कमांड crontab -eको उस डायरेक्टरी से चला सकता हूं जहां मेरी पाइथन स्क्रिप्ट है .. सही है?
शस्त्रागार

1
@Webby आप इसे अपनी इच्छानुसार कहीं से भी चला सकते हैं। cronएक शेड्यूलिंग डेमॉन है, यह एक ऐसी सेवा है जो पृष्ठभूमि में चलती है। यदि आपकी पायथन लिपि आपके अंदर नहीं है $PATH(यदि आप इसे कहीं से भी लॉन्च नहीं कर सकते हैं, लेकिन इसके डायरेक्टरी में होने की आवश्यकता है) तो स्क्रिप्ट का पूरा पथ मेरे अद्यतन उत्तर में उपयोग करें।
terdon

धन्यवाद। अब यह समझ में आता है .. मैंने अभी एक नया crontab बनाया है और एक ही पंक्ति को जोड़कर फ़ाइल को संपादित किया है लेकिन 1 मिनट के लिए .. मैंने पहले ही एक हैलो वर्ल्ड पायथन स्क्रिप्ट बनाई है, जिसमें घूमते हुए ट्रू नाम दिया गया है .. सहेजने के बाद crontab फ़ाइल, इसे 1 मिनट के बाद स्वचालित रूप से टेस्टिंगहोम प्रारंभ करना चाहिए? और फिर हर 1 मिनट में चेक करते रहें कि अजगर स्क्रिप्ट चला रहा है या नहीं? यदि हाँ, crontab -e फ़ाइल को सहेजने के बाद, मैंने ps ax किया | grep test.py और मैं उसके लिए कोई प्रक्रिया नहीं देख पा रहा हूँ?
शस्त्रागार

6

आप एक कमांडलाइन विकल्प का उपयोग करके परीक्षण प्रोग्राम को पुनर्निर्देशित कर सकते हैं और फिर कार्यक्रम को अनिश्चित काल के लिए फिर से शुरू करने के लिए एक साधारण अजगर स्क्रिप्ट का उपयोग कर सकते हैं:

import subprocess

while True:
    try:
        print subprocess.check_output(['python', 'testing.py'])
    except KeyboardInterrupt:
        break

आप इस कार्यक्रम को पृष्ठभूमि में रख सकते हैं, और एक बार जब आप इसे केवल अग्रभूमि में खींचना बंद कर देते हैं और इसे मार देते हैं।


6

आपको वास्तव में उत्पादन के लिए इसका उपयोग नहीं करना चाहिए, लेकिन आप कर सकते हैं:

#!/bin/sh

while true; do
  nohup python testing.py >> test.out
done &

यदि, किसी भी कारण से, अजगर प्रक्रिया से बाहर निकलता है, तो शेल लूप जारी रहेगा और इसे पुनः आरंभ करेगा, .outफ़ाइल को वांछित के रूप में जोड़ देगा। लगभग कोई ओवरहेड नहीं है और सेट होने में बहुत कम समय लगता है।


6

UNIX / Linux के तहत प्रक्रियाओं की निगरानी और प्रतिक्रिया करने के कई तरीके हैं। सबसे पुराने में से एक / रिस्पॉन्स / इनिटैब / में प्रवेश है ... यदि आप पुराने SysV इनिट सिस्टम का उपयोग कर रहे हैं। एक और तरीका डीजे बर्नस्टीन के डेमोंटोल्स पैकेज से पर्यवेक्षक डेमन का उपयोग करना है । अन्य विकल्प उबंटू अपस्टार्ट ... या सिस्टमड या अन्य में सुविधाओं का उपयोग करने के लिए हैं।

लेकिन आप वैकल्पिक इनिट और पर्डस के लिए पायथन कोड में देख सकते हैं : विशेष रूप से मुद्रा दामन

यदि आप क्रोन जॉब (और पीआईडी ​​फाइल हैंडलिंग) के साथ जाने का निर्णय लेते हैं तो इस पीईपी 3143 को पढ़ने और शायद इसके संदर्भ कार्यान्वयन का उपयोग करने पर विचार करें।

जैसा कि मैंने अपनी अन्य टिप्पणियों में बताया, मजबूत पीआईडी ​​फाइल हैंडलिंग मुश्किल है। यह दौड़ और कोने के मामलों के लिए प्रवण है। यह मुश्किल हो जाता है अगर कोई मौका है कि आपकी पीआईडी ​​फाइल एनएफएस या अन्य नेटवर्क फाइल सिस्टम पर समाप्त हो जाती है (कुछ एटोमिक गारंटी आपको फ़ाइल को उचित स्थानीय यूनिक्स / लिनक्स फाइलसिस्टम पर सिमेंटिक्स को संभालने के साथ मिलती है, तो कुछ संस्करणों और एनएफएस के कार्यान्वयन पर चले जाते हैं, उदाहरण के लिए)। इसके अलावा UNIX के तहत फाइल लॉकिंग के आसपास शब्दार्थ मुश्किल हो सकता है। (क्या एक flockया fcntlताला, तुरंत जारी किया हो, अपने लक्ष्य ओएस में जब यह पकड़े प्रक्रिया उदाहरण के लिए, SIGKILL साथ मार दिया जाता है?)।


3

आप ps-watcher के साथ monit या Process मॉनीटरिंग का भी उपयोग कर सकते हैं

मॉनेट एक UNIX प्रणाली पर प्रबंधन और निगरानी, ​​प्रक्रियाओं, कार्यक्रमों, फाइलों, निर्देशिकाओं और फाइल सिस्टम के लिए एक खुला स्रोत उपयोगिता है। मोनिट स्वचालित रखरखाव और मरम्मत करता है और त्रुटि स्थितियों में सार्थक कार्यवाहियों को निष्पादित कर सकता है।

यहाँ आपके परिदृश्य के लिए उदाहरण है:

check process myprocessname
        matching "myprocessname"
        start program = "nohup /usr/bin/python /path/testing.py > /tmp/test.out &"
        stop program = "/usr/bin/killall myprocessname"

मोनिट के उदाहरणों को देखें


1

आपको एक पर्यवेक्षक की आवश्यकता है, आप पर्यवेक्षक का उपयोग कर सकते हैं । यह अजगर आधारित पर्यवेक्षक है, इसलिए यदि आवश्यक हो तो संशोधित करना आसान है।

नियंत्रण .ini फ़ाइल सिंटैक्स वाली फ़ाइलों के साथ है।


0

टेरडन का जवाब, मेरे लिए काम नहीं करता pgrep -f testing.pyथा , क्योंकि कभी भी 'असफल' नहीं हुआ था। यह क्रॉन जॉब के लिए pid को हड़प लेगा (-f विकल्प के कारण)। हालाँकि, -f विकल्प के बिना pgrep को टेस्टिंगहोम नहीं मिलेगा क्योंकि टेस्टिंगहोम नामक कोई प्रक्रिया नहीं है।

इसका मेरा हल बदलना था

pgrep -f testing.py

सेवा मेरे

pgrep -f testing.py | pgrep python

इसका मतलब है कि पूर्ण क्रेस्टैब काम होगा:

*/5 * * * * pgrep -f testing.py | pgrep python || nohup python /home/you/scripts/testing.py > test.out

0

मेरे मामले में, एक त्वरित-फिक्स के रूप में, मैं अपने कार्यक्रम को चालू रखना चाहता था जब वह एन त्रुटि के साथ बाहर निकलता था या उसे मार दिया जाता था। दूसरी ओर, मैं प्रोग्राम को सही ढंग से समाप्त करने पर निष्पादन को रोकना चाहता था (रिटर्न कोड = 0)

मैंने इसका परीक्षण बैश पर किया है। यह किसी अन्य शेल में ठीक काम करना चाहिए

#!/bin/sh

echo ""
echo "Use: $0 ./instagram.py"
echo ""

echo "Executing $1 ..."

EXIT_CODE=1
(while [ $EXIT_CODE -gt 0 ]; do
    $1
    # loops on error code: greater-than 0
    EXIT_CODE=$?
done)

0

टेर्डन के उत्तर के लिए, यहाँpgrep -f testing.py टिप्पणियों के अनुसार कभी भी गलत नहीं लौटेंगे :

मुझे लगता है कि समस्या यह है कि क्रॉन आपकी कमांड को चलाने के लिए एक शेल खोल देता है, और उस शेल के तर्कों को pgrep द्वारा मिलान किया जाता है क्योंकि आप उपयोग कर रहे हैं -f

मैट के जवाब के लिए, किसी भी चल रहे पायथन स्क्रिप्ट pgrep -f testing.pyसे pgrep pythonमेल खाने के बाद से बेकार है । इसलिए अगर दो पायथन लिपि क्रोनजॉब, दूसरी क्रोनजॉब कभी नहीं चलेगी।

और फिर मुझे pgrep -f testing.pyयहाँ टिप्पणी में हल करने का उपाय मिला : https://askubuntu.com/questions/1014559/running-pgrep-in-a-crontab?noredirect=1&lq=1

दो पायथन स्क्रिप्ट चलाने के लिए मेरा क्रोन:

* * * * * pgrep -f '^/usr/bin/python36 /home/ec2-user/myscript1\.py' || nohup /usr/bin/python36 /home/ec2-user/myscript1.py

0 * * * * pgrep -f '^/usr/bin/python36 /home/ec2-user/myscript2\.py' || nohup /usr/bin/python36 /home/ec2-user/myscript2.py
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.