मेरे पास एक प्रक्रिया है जो पहले से ही लंबे समय से चल रही है और इसे समाप्त नहीं करना चाहती।
मैं इसे नोह के नीचे कैसे डाल सकता हूं (अर्थात, मैं इसे कैसे चालू रख सकता हूं, भले ही मैं टर्मिनल बंद कर दूं?)
मेरे पास एक प्रक्रिया है जो पहले से ही लंबे समय से चल रही है और इसे समाप्त नहीं करना चाहती।
मैं इसे नोह के नीचे कैसे डाल सकता हूं (अर्थात, मैं इसे कैसे चालू रख सकता हूं, भले ही मैं टर्मिनल बंद कर दूं?)
जवाबों:
प्रक्रिया को पृष्ठभूमि में भेजने के लिए बैश के जॉब कंट्रोल का उपयोग करना :
bg इसे पृष्ठभूमि में चलाने के लिए।disown -h [job-spec]जहां [job-spec] जॉब नंबर है (जैसे %1पहले चलने वाले जॉब के लिए; jobsकमांड के साथ अपने नंबर के बारे में पता करें ) ताकि टर्मिनल बंद होने पर जॉब न मारे।disown -hशायद अधिक सटीक उत्तर है: "अवहेलना करें और अधिक व्यवहार करें जैसे नोह (यानी नौकरियां आपके वर्तमान शेल की प्रक्रिया के पेड़ में रहेंगी जब तक आप अपने शेल से बाहर नहीं निकल जाते हैं) यह आपको देखने की अनुमति देता है सभी नौकरियों कि यह खोल शुरू कर दिया। " ([ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… ) से
disown, एक प्रक्रिया डिमॉन बनाती है, जिसका अर्थ है कि मानक इनपुट / आउटपुट को / dev / null पर पुनर्निर्देशित किया जाता है। इसलिए, यदि आप किसी नौकरी को my_job_command | tee my_job.log
मान लीजिए किसी कारण से Ctrl+ Zभी काम नहीं कर रहा है, दूसरे टर्मिनल पर जाएं, प्रक्रिया आईडी ढूंढें (उपयोग करके ps) और चलाएं:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOPप्रक्रिया को निलंबित करेगा और SIGCONTप्रक्रिया को पृष्ठभूमि में फिर से शुरू करेगा। तो अब, अपने दोनों टर्मिनलों को बंद करने से आपकी प्रक्रिया बंद नहीं होगी।
disown %1इसे बंद करने से पहले पहले टर्मिनल में करना याद रखें ।
kwinपरिणाम के बारे में सोचे बिना एक दुर्घटना के बाद कोनोला से शुरू हुआ)। इसलिए अगर मैं केविन को रोक देता, तो सब कुछ जम जाता और मुझे दौड़ने की कोई संभावना नहीं होती bg!
रनिंग जॉब को शेल से अलग करने की कमांड (= इसे nohup बनाता है) disownऔर एक बेसिक शेल-कमांड है।
बैश-मैनपेज (मैन बैश) से:
disown [-ar] [-h] [jobspec ...]
विकल्पों के बिना, प्रत्येक कार्यक्षेत्र को सक्रिय नौकरियों की तालिका से हटा दिया जाता है। यदि -एच विकल्प दिया जाता है, तो प्रत्येक जॉबस्पेक को टेबल से नहीं हटाया जाता है, लेकिन इसे चिह्नित किया जाता है, ताकि शेल को राइट्स प्राप्त होने पर साइट पर काम न भेजा जाए। यदि कोई जॉबस्पेक मौजूद नहीं है, और न तो -a और -r विकल्प की आपूर्ति की जाती है, तो वर्तमान नौकरी का उपयोग किया जाता है। यदि कोई जॉबस्पेक की आपूर्ति नहीं की जाती है, तो सभी विकल्पों को हटाने या चिह्नित करने के लिए -a विकल्प का अर्थ है; नौकरी के तर्क के बिना -r विकल्प रनिंग जॉब के लिए ऑपरेशन को प्रतिबंधित करता है। रिटर्न वैल्यू 0 है जब तक कि जॉबस्पेक एक वैध नौकरी निर्दिष्ट नहीं करता है।
इसका मतलब है, कि एक सरल
disown -a
जॉब-टेबल से सभी नौकरियों को निकाल देगा और उन्हें नोहप बना देगा
disown -aसभी नौकरियों को निकालता है। एक साधारण disownकेवल वर्तमान नौकरी को हटा देता है। जैसा कि उत्तर में मैन पेज कहता है।
ये ऊपर अच्छे जवाब हैं, मैं सिर्फ एक स्पष्टीकरण जोड़ना चाहता था:
आप एक काम disownया प्रक्रिया नहीं कर सकते , आप disownएक नौकरी है, और यह एक महत्वपूर्ण अंतर है।
एक नौकरी एक ऐसी चीज है जो एक ऐसी प्रक्रिया की धारणा है जो एक शेल से जुड़ी हुई है, इसलिए आपको नौकरी को पृष्ठभूमि में फेंकना होगा (इसे निलंबित नहीं करना चाहिए) और फिर इसे भंग कर दिया।
मुद्दा:
% jobs
[1] running java
[2] suspended vi
% disown %1
यूनिक्स जॉब कंट्रोल की अधिक विस्तृत चर्चा के लिए http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ देखें ।
दुर्भाग्य disownसे सभी गोले में उपलब्ध नहीं है।
यूनिक्स के कुछ जायके (जैसे AIX और Solaris) के पास nohupकमांड पर ही एक विकल्प होता है जिसे एक रनिंग प्रोसेस पर लागू किया जा सकता है:
nohup -p pid
AIXऔर के लिए Solaris। "नोक के AIX और सोलारिस संस्करणों के पास एक -p विकल्प है जो भविष्य में होने वाले सिग्नल संकेतों को अनदेखा करने के लिए एक रनिंग प्रक्रिया को संशोधित करता है। बैश के उपर्युक्त वर्णित बिलिन के विपरीत, nohup -p प्रक्रिया आईडी को स्वीकार करता है।" स्रोत
नोड का उत्तर वास्तव में बहुत अच्छा है, लेकिन इसने इस सवाल को खोल दिया कि कैसे स्टडआउट और स्टेडर पुनर्निर्देशित हो सकते हैं। मुझे यूनिक्स और लिनक्स पर एक समाधान मिला , लेकिन यह भी पूरा नहीं हुआ है। मैं इन दोनों समाधानों का विलय करना चाहूंगा। यह रहा:
अपने परीक्षण के लिए मैंने लूप.श नाम की एक छोटी सी बैश स्क्रिप्ट बनाई, जो एक अनंत लूप में एक मिनट की नींद के साथ अपने आप को प्रिंट करती है।
$./loop.sh
अब इस प्रक्रिया का पीआईडी किसी तरह हासिल करें। आमतौर पर ps -C loop.shयह काफी अच्छा है, लेकिन यह मेरे मामले में छपा है।
अब हम दूसरे टर्मिनल पर जा सकते हैं (या ^ Z और उसी टर्मिनल में दबाएँ)। अब gdbइस प्रक्रिया से जुड़ा होना चाहिए।
$ gdb -p <PID>
यह स्क्रिप्ट को रोकता है (यदि चल रहा है)। इसकी स्थिति को चेक किया जा सकता है ps -f <PID>, जहां STATफ़ील्ड 'T +' है (या ^ Z 'T' के मामले में), जिसका अर्थ है (मैन ps (1))
T Stopped, either by a job control signal or because it is being traced
+ is in the foreground process group
(gdb) call close(1)
$1 = 0
बंद (1) सफलता पर शून्य देता है।
(gdb) call open("loop.out", 01102, 0600)
$6 = 1
ओपन (1) सफल होने पर नई फाइल डिस्क्रिप्टर लौटाता है।
यह खुला के साथ बराबर है open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)। के बजाय O_RDWR O_WRONLYलागू किया जा सकता है, लेकिन /usr/sbin/lsofसभी std * फ़ाइल हैंडलर ( FDकॉलम) के लिए 'u' कहते हैं , जो है O_RDWR।
मैंने /usr/include/bits/fcntl.h हैडर फ़ाइल में मानों की जाँच की।
आउटपुट फ़ाइल के साथ खोला जा सकता है O_APPEND, जैसा nohupकि होगा, लेकिन यह man open(2)संभव NFS समस्याओं के कारण, द्वारा सुझाया नहीं गया है।
यदि हमें रिटर्न मान के रूप में -1 मिलता है, तो call perror("")त्रुटि संदेश प्रिंट करता है। अगर हमें ग़लती की ज़रूरत है, तो p errnogdb comand का उपयोग करें ।
अब हम नई पुनर्निर्देशित फ़ाइल की जांच कर सकते हैं। /usr/sbin/lsof -p <PID>प्रिंट:
loop.sh <PID> truey 1u REG 0,26 0 15008411 /home/truey/loop.out
अगर हम चाहते हैं, हम एक और फाइल करने के लिए stderr अनुप्रेषित अगर हम का उपयोग कर करना चाहते हैं कर सकते हैं call close(2)और call open(...)फिर एक अलग फ़ाइल नाम का उपयोग।
अब संलग्न bashको जारी करना होगा और हम छोड़ सकते हैं gdb:
(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q
यदि स्क्रिप्ट को gdbकिसी अन्य टर्मिनल से रोका गया था तो यह चलता रहता है। हम लूप.श टर्मिनल पर वापस जा सकते हैं। अब यह स्क्रीन के लिए कुछ भी नहीं लिखता है, लेकिन फ़ाइल में चल रहा है और लिख रहा है। हमें इसे पृष्ठभूमि में रखना होगा। तो दबाओ ^Z।
^Z
[1]+ Stopped ./loop.sh
(अब हम उसी स्थिति में हैं जैसे ^Zकि शुरुआत में दबाया गया था।)
अब हम नौकरी की स्थिति की जांच कर सकते हैं:
$ ps -f 24522
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID><PPID> 0 11:16 pts/36 S 0:00 /bin/bash ./loop.sh
$ jobs
[1]+ Stopped ./loop.sh
इसलिए प्रक्रिया को पृष्ठभूमि में चलना चाहिए और टर्मिनल से अलग होना चाहिए। jobsवर्गाकार कोष्ठकों में कमांड के आउटपुट में संख्या अंदर की नौकरी की पहचान करती है bash। bashजॉब नंबर से पहले '%' साइन अप करने वाले कमांड में निर्मित हम निम्न में उपयोग कर सकते हैं :
$ bg %1
[1]+ ./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID><PPID> 0 11:16 pts/36 S 0:00 /bin/bash ./loop.sh
और अब हम कॉलिंग बैश से बाहर निकल सकते हैं। प्रक्रिया पृष्ठभूमि में चलती रहती है। यदि हम इसकी PPID 1 (init (1) प्रक्रिया) बन जाते हैं और नियंत्रण टर्मिनल अज्ञात हो जाता है।
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID> 1 0 11:16 ? S 0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey 0u CHR 136,36 38 /dev/pts/36 (deleted)
loop.sh <PID> truey 1u REG 0,26 1127 15008411 /home/truey/loop.out
loop.sh <PID> truey 2u CHR 136,36 38 /dev/pts/36 (deleted)
टिप्पणी
Gdb सामान को एक फाइल बनाते हुए स्वचालित किया जा सकता है (जैसे loop.gdb) जिसमें कमांड होते हैं और चलते हैं gdb -q -x loop.gdb -p <PID>। मेरा लूप। एसजीडी इस तरह दिखता है:
call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit
या इसके बजाय निम्नलिखित एक लाइनर का उपयोग कर सकते हैं:
gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>
मुझे उम्मीद है कि यह समाधान का एक पूर्ण विवरण है।
lsof(फ़ाइल हैंडल का नाम ऐसा pipeनहीं है /dev/pts/1) या द्वारा ls -l /proc/<PID>/fd/<fd>(यह हैंडल के सिम्लिंक को दर्शाता है)। इसके अलावा सबप्रोसेस में अभी भी रीडायरेक्ट किए गए आउटपुट नहीं हो सकते हैं, जिन्हें किसी फाइल में रीडायरेक्ट किया जाना चाहिए।
Nohup ( http://en.wikipedia.org/wiki/Nohup ) को रनिंग प्रक्रिया भेजने के लिए
nohup -p pid , यह मेरे लिए काम नहीं किया
फिर मैंने निम्नलिखित आदेशों को आजमाया और यह बहुत अच्छा काम किया
कुछ SOMECOMMAND चलाएं, कहते हैं /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1।
Ctrl+ Zकार्यक्रम को रोकने (रोकने) और वापस शेल में जाने के लिए।
bg इसे पृष्ठभूमि में चलाने के लिए।
disown -h टर्मिनल बंद होने पर प्रक्रिया को नहीं मारा जाता है।
exitशेल से बाहर निकलने के लिए टाइप करें क्योंकि अब आप जाने के लिए अच्छा है क्योंकि ऑपरेशन अपनी प्रक्रिया में पृष्ठभूमि में चलेगा, इसलिए यह शेल से बंधा नहीं है।
यह प्रक्रिया चलने के बराबर है nohup SOMECOMMAND।
bg - यह काम को पृष्ठभूमि में रखेगा और चलने की प्रक्रिया में वापस लौटेगाdisown -a - यह नौकरी के साथ सभी लगाव में कटौती करेगा (इसलिए आप टर्मिनल को बंद कर सकते हैं और यह अभी भी चलेगा)ये सरल चरण आपको प्रक्रिया को चालू रखते हुए टर्मिनल को बंद करने की अनुमति देंगे।
यह nohupआपके प्रश्न की मेरी समझ के आधार पर नहीं लगाया जाएगा , आपको इसकी आवश्यकता नहीं है)।
yourExecutable &और आउटपुट स्क्रीन पर आते रहें औरCtrl+Cकुछ भी बंद न हो, बस आँख बंद करके टाइप करेंdisown;औरEnterस्क्रीन को आउटपुट के साथ स्क्रॉल करने पर भी दबाएँ और आप यह नहीं देख सकते कि क्या आप टाइप कर रहे हैं। यह प्रक्रिया समाप्त हो जाएगी और आप बिना प्रक्रिया के मरने के बाद टर्मिनल को बंद कर पाएंगे।