स्क्रिप्ट से पृष्ठभूमि की प्रक्रिया शुरू करें और स्क्रिप्ट समाप्त होने पर इसे प्रबंधित करें


15

मैं एक स्क्रिप्ट से एक डेमन के समान प्रक्रिया को चलाना और कॉन्फ़िगर करना चाहूंगा।
मेरा खोल Cygwin के तहत zsh है और डेमॉन SFK , एक मूल एफ़टीपी सर्वर है।

यहाँ क्या मायने रखता है, इसके लिए स्क्रिप्ट startserv.shको प्रारूपित किया जा सकता है:

#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
$cmd &

स्क्रिप्ट चलाने के बाद startserv.sh, यह बिना किसी संकेत के, बिना रुके समाप्त हो जाता है, फिर:

  • CTRL+ Cस्क्रिप्ट और पृष्ठभूमि नौकरी प्रक्रिया दोनों को समाप्त करता है;

  • Enterस्क्रिप्ट को हिट करने से पृष्ठभूमि में प्रक्रिया समाप्त हो जाती है।

वैसे भी मैं इसे केवल के माध्यम से देख सकता हूं psऔर नहीं jobs, इसलिए, जब मैं इस प्रक्रिया को बंद करना चाहता हूं, तो मुझे एक क्रूर kill -9संकेत भेजना होगा , जो कि मैं CTRL+ के पक्ष में बचना चाहता हूं C

एक वैकल्पिक पृष्ठभूमि में पूरी स्क्रिप्ट चल रही होगी । 'होगा', लेकिन readस्क्रिप्ट के रूप में चलाने पर कमांड को उपयोगकर्ता इनपुट नहीं मिल पाता है startserv.sh &

ध्यान दें कि मुझे एक अल्पकालिक सर्वर की आवश्यकता है, एक सच्चा डेमॉन नहीं : अर्थात, मैं चाहता हूं कि सर्वर प्रक्रिया पृष्ठभूमि में चलने के बाद, स्क्रिप्ट समाप्त होने के बाद, सरल इंटरैक्टिव शैल कार्यों (एक वर्चुअल मशीन अतिथि के साथ) करने के लिए, लेकिन मैं डॉन ' टी को जीवित रहने के लिए प्रक्रिया की आवश्यकता है; इसलिए nohupउचित नहीं लगता।


प्रक्रिया के प्रोसेस आईडी को बैकग्राउंड में चलाकर उपयोग करें bgproc="$!"और फिर command "$bgproc" उचित कार्रवाई करें। यह भी देखें stackoverflow.com/questions/1908610/…
वैलेंटाइन बजरमी

आप एक PID फ़ाइल भी बना सकते हैं। फिर उस फ़ाइल को पढ़ें कि यह क्या प्रक्रिया संख्या है और वहां से जाएं।
jgr208 16

जवाबों:


18

Enterस्क्रिप्ट को हिट करने से पृष्ठभूमि में प्रक्रिया समाप्त हो जाती है।

लगभग! दरअसल, आपके द्वारा दबाए गए समय से स्क्रिप्ट पहले ही बाहर हो गई है Enter। हालाँकि, यह है कि आप अपना संकेत कैसे वापस पा सकते हैं (क्योंकि आपका शेल $PS1फिर से अपने सभी प्रिंट करता है )।

दोनों को मारना Ctrl+ Cसमाप्त करने का कारण यह है कि इन दोनों को जोड़ा जाता है। जब आप अपनी स्क्रिप्ट निष्पादित करते हैं, तो आपका शेल एक सब-आरंभ करता है जिसमें इसे चलाना है। जब आप इस उपधारा को समाप्त करते हैं, तो आपकी पृष्ठभूमि प्रक्रिया मर जाती है, शायद एक SIGHUPसंकेत से।

स्क्रिप्ट, पृष्ठभूमि प्रक्रिया और उपधारा अलग करें

का उपयोग कर nohup, आप इस छोटी सी असुविधा से छुटकारा पाने में सक्षम हो सकते हैं।

#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
nohup $cmd &

disownविकल्प

आप से स्विच कर सकते हैं /bin/shकरने के लिए /bin/bash, आप के लिए एक कोशिश दे सकते हैं disownऔर साथ ही। अधिक जानने के लिए सिर्फ टाइप help disownएक में bashउदाहरण।

disown -h $cmd &

"अच्छी तरह से" पृष्ठभूमि की प्रक्रिया को मारना

अब, जब आपकी प्रक्रिया को मारने की बात आती है, तो आप पूरी तरह से " Ctrl+ C" का उपयोग कर सकते हैं kill। बस एक क्रूर मत भेजो SIGKILL। इसके बजाय, आप उपयोग कर सकते हैं:

$ kill -2 [PID]
$ kill -15 [PID]

जो आपकी प्रक्रिया में एक अच्छा SIGINT(2) या SIGTERM(15) भेजेगा । आप प्रक्रिया शुरू करने के बाद PID मान प्रिंट करना चाहते हैं:

...
nohup $cmd &
echo $!

... या इससे भी बेहतर, स्क्रिप्ट को प्रतीक्षा करें SIGINT, और इसे पृष्ठभूमि प्रक्रिया में वापस भेजें (यह आपकी स्क्रिप्ट को अग्रभाग में रखेगा) :

#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
nohup $cmd &

# Storing the background process' PID.
bg_pid=$!

# Trapping SIGINTs so we can send them back to $bg_pid.
trap "kill -2 $bg_pid" 2

# In the meantime, wait for $bg_pid to end.
wait $bg_pid

यदि SIGINTपर्याप्त नहीं है, तो बस SIGTERMइसके बजाय (15) का उपयोग करें :

trap "kill -15 $bg_pid" 2 15

इस तरह, जब आपकी स्क्रिप्ट को पृष्ठभूमि प्रक्रिया के लिए एक SIGINT( Ctrl+ ) C, kill -2या SIGTERMथोड़ी देर प्राप्त waitहोती है, तो यह केवल इसके संकेतों को रिले कर देगा। यदि ये संकेत sfkआवृत्ति को मारते हैं , तो waitकॉल वापस आ जाएगी, इसलिए आपकी स्क्रिप्ट को भी समाप्त कर दिया जाएगा :)


1
+1 बहुत जानकारीपूर्ण। चूंकि स्क्रिप्ट एक उपधारा में चलती है, लिपि के स्क्रिप्ट के मूल शेल के जॉब टेबल तक पहुंचने की कोई संभावना है? वह लिस्ट jobsसमाप्त होने के बाद टर्मिनल में जारी होने वाली नौकरियां हैं (इसके बजाय ps)।
एंटोनियो

1
नौकरियां आपके वर्तमान शेल से जुड़ी होती हैं, वे एक शेल से दूसरे में प्रसारित नहीं होती हैं। जब आपकी सदस्यता समाप्त हो जाती है, तो इसकी नौकरियां वापस नहीं मिलती हैं। अपनी पृष्ठभूमि प्रक्रिया 'PID' को प्रिंट करके, आप यह सुनिश्चित करते हैं कि उपधारा समाप्त होने ( pid -p) के बाद भी आप इसके बारे में आसानी से जानकारी प्राप्त कर सकते हैं ।
जॉन डब्ल्यूएच

अच्छी व्याख्या, हालांकि यदि आपकी स्क्रिप्ट में अधिक कमांड हैं, तो वे कभी भी निष्पादित नहीं होते हैं (क्योंकि wait)। यदि आप प्रतीक्षा को हटाते हैं, तो सिग्नल हैंडलिंग टूट गई है: /
शेफारोव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.