मैं `और` का उपयोग कर रहा हूं: पृष्ठभूमि में प्रक्रिया क्यों नहीं चल रही है?


24

मुझे पता है कि मैं &पृष्ठभूमि में प्रक्रिया को चलाने के लिए एक कमांड के लिए अपील कर सकता हूं ।

मैं एक उबंटू 12.04 बॉक्स में SSH'ing कर रहा हूं और इसके साथ एक अजगर कार्यक्रम चला $python program.py &रहा हूं - लेकिन जब मैं टर्मिनल विंडो को बंद करने के लिए जाता हूं तो मुझे एक संदेश मिलता है जिसमें कहा जाता है कि टर्मिनल को बंद करने से रनिंग प्रक्रिया समाप्त हो जाएगी।

ऐसा क्यों है? मैं पृष्ठभूमि में प्रक्रिया को चलाने के लिए एम्परसेंड का उपयोग कर रहा हूं। अगर मैं SSH'ed में हूं तो मैं इसे कैसे चला सकता हूं?



apt-get install स्क्रीन, मैन स्क्रीन
कैप्चा

जवाबों:


51

जब आप एक टर्मिनल विंडो बंद करते हैं, तो टर्मिनल एमुलेटर आपके द्वारा चलाए जा रहे प्रोसेस को एक SUPUP भेजता है। आपका शेल उसके बाद से चल रहा है कि सब कुछ करने के लिए SIGHUP। आपके स्थानीय सिस्टम पर, यह ssh है। तब ssh आगे चल रहा है, जो रिमोट शेल है। तो आपका रिमोट शेल तब अपने सभी प्रोसेस, आपके बैकग्राउंड प्रोग्राम के लिए एक SITEUP भेजता है।

इसके आसपास 2 तरीके हैं।

  1. अपने शेल से पृष्ठभूमि वाले प्रोग्राम को अलग करें।
    1. disownअपनी प्रक्रिया की पृष्ठभूमि के बाद कमांड का उपयोग करें । यह खोल को इसके बारे में भूल जाएगा।
    2. nohup( nohup $python program.py &) के साथ अपने आदेश को उपसर्ग करें । यह एक ही बात को पूरा करता है, लेकिन एक मध्यवर्ती प्रक्रिया का उपयोग करके। मूल रूप से यह SIGHUP सिग्नल को अनदेखा करता है, और फिर आपके प्रोग्राम को फोर्क्स & निष्पादित करता है जो सेटिंग को इनहेरिट करता है, और फिर बाहर निकलता है। क्योंकि यह कांटा गया, लॉन्च किया जा रहा प्रोग्राम शेल का बच्चा नहीं है, और शेल को इसके बारे में पता नहीं है। और जब तक यह SIGHUP के लिए सिग्नल हैंडलर स्थापित नहीं करता है, यह वैसे भी अनदेखा कार्रवाई को बनाए रखता है।
  2. logoutटर्मिनल विंडो को बंद करने के बजाय उपयोग करें । जब आप उपयोग करते हैं logout, तो यह एक SITEUP नहीं है, और इसलिए शेल अपने किसी भी बच्चे को SITEUP नहीं भेजेगा।

इसके अतिरिक्त आपको यह सुनिश्चित करना होगा कि आपका प्रोग्राम STDOUT या STDERR के माध्यम से टर्मिनल को नहीं लिखे, क्योंकि टर्मिनल से बाहर निकलते ही उन दोनों का अस्तित्व नहीं रहेगा। यदि आप उन्हें किसी चीज़ की तरह पुनर्निर्देशित नहीं करते हैं /dev/null, तो प्रोग्राम अभी भी चलेगा, लेकिन अगर यह उन्हें लिखने की कोशिश करता है, तो उसे एक SIGPIPE मिलेगा, और SIGPIPE की डिफ़ॉल्ट कार्रवाई प्रक्रिया को मारना है)।


4
तकनीकी रूप से, sshमरने के कारण कनेक्शन गिर जाता है, ड्रॉप करने के लिए कनेक्शन sshdदूसरे छोर पर मरने का कारण बनता है । यह छद्म टर्मिनल के मास्टर पक्ष को नियंत्रित करने वाला sshd है जो दूरस्थ शेल चलाता है, जब वह मर जाता है, तो वह हैंग-अप (यह एक वास्तविक टर्मिनल पर प्लग खींचने जैसा है), इसलिए सिस्टम रिमोट शेल को एक SIGHUP भेजता है।
स्टीफन चेज़लस

@ स्टीफनचेज़लस एक ऐसी चीज़ है जिसे मैंने कभी नहीं खोदा है। यदि यह कर्नेल कर रहा है, तो यह कैसे निर्धारित करता है कि किस प्रक्रिया के लिए SITEUP? यह स्पष्ट रूप से उस TTY के लिए एक ओपन फ़ाइल डिस्क्रिप्टर के साथ सब कुछ SUPUP नहीं करता है, क्योंकि जब तक वे इसका उपयोग करने की कोशिश नहीं करेंगे, कार्यक्रम चलते रहेंगे। तो क्या यह उस कार्यक्रम को चुनता है जो वर्तमान में STDIN से पढ़ रहा है (क्योंकि एक समय में केवल STDIN से ही पढ़ा जा सकता है)?
पैट्रिक

4
कोई बात नहीं, मेरे अपने सवाल का जवाब दिया। POSIX IEEE 1003.1 चैप 11, अगर एक मॉडेम डिस्कनेक्ट का पता टर्मिनल इंटरफ़ेस द्वारा एक कंट्रोलिंग टर्मिनल के लिए लगाया जाता है ... तो SIGHUP सिग्नल को कंट्रोलिंग प्रोसेस में भेजा जाएगा
पैट्रिक

2
यह भी ध्यान दें कि आपके द्वारा शुरू किए गए प्रोग्राम के आउटपुट के साथ nohupएक nohup.outफ़ाइल उत्पन्न करता है। हर बार जब आप इस तरह से ऐप शुरू करने के लिए nohup का उपयोग करते हैं, तो उस फ़ाइल को हटाने के लिए कष्टप्रद हो सकता है (या आपको इसके आउटपुट को पुनर्निर्देशित करना होगा /dev/null)।
रुस्लान

1
इसके बजाय nohup python program.py &मैं इसके बजाय उपयोग setsid python program.pyकरने की सलाह दूंगा, जो तुरंत कार्यक्रम को भंग कर देता है।
हाईटेककंप्यूटरजेक

14

प्रक्रिया टर्मिनल में पृष्ठभूमि में चल रही है, लेकिन अभी भी stdout(और stderr) से आउटपुट टर्मिनल पर भेजा जा रहा है। इसे रोकने के लिए, दोनों आउटपुट को पुनर्निर्देशित करने > /dev/null 2>&1से पहले जोड़ें - यह भी सुनिश्चित करें कि टर्मिनल बंद करने के बाद प्रक्रिया को नहीं मारा गया है:&/dev/nulldisown

COMMAND > /dev/null 2>&1 & disown

आपके मामले में यह होगा:

python program.py > /dev/null 2>&1 & disown

3

&ऑपरेटर अलग आदेशों समानांतर में चलाने के लिए, बस के रूप में ;अलग आदेशों श्रृंखला में चलाने के लिए। दोनों प्रकार के आदेश अभी भी शेल प्रक्रिया के एक बच्चे के रूप में चलेंगे

इसलिए, जब आप उन बच्चों को खोलना बंद कर देते हैं जो बच्चों को शुरू करते हैं, तो बच्चे भी बंद हो जाएंगे।

आप जो चाहते हैं वह एक डेमन प्रक्रिया है , जो काफी अधिक मुश्किल है क्योंकि इसे मूल प्रक्रिया से पूरी तरह से अलग करने की आवश्यकता है। खोल आमतौर पर ऐसा करने का एक सरल तरीका नहीं है।


1

जब आप लॉगआउट करते हैं, तो लॉगिन सत्र से जुड़ी पृष्ठभूमि प्रक्रियाएं सामान्य रूप से भी मार दी जाती हैं। यदि आप चाहते हैं कि उन्हें सत्र से काट दिया जाए, तो उन्हें चलाएं nohup

nohup python program.py &

1

&कमांड प्रॉम्प्ट पर ampersand ( ) के साथ समाप्त होने के बाद, कमांड चलाएं bg:

bash> python program.py &  
bash> bg  

यह "&" कमांड को पृष्ठभूमि में रखेगा

bash> jobs  

यह पृष्ठभूमि में चल रही नौकरियों को सूचीबद्ध करेगा

bash> fg 1   

यह अय्यूब # 1 को अग्रभूमि में लाएगा

दूसरा तरीका, (लॉग आउट करने में सक्षम होना)

bash> at now  
bash> /full/path/python /full/path/program.py  
bash> ^d   `(# That is, Control-D, to run the command, Control-C to cancel)`  

at^ D (Control-D)
देखने से पहले कमांड में कई लाइनें सबमिट की जा सकती हैं man at

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