मैं बैश स्क्रिप्ट से एक प्रक्रिया को कैसे अलग कर सकता हूं?


18

मैं एक बैश स्क्रिप्ट से एक प्रक्रिया को अलग करने की कोशिश कर रहा हूं ताकि स्क्रिप्ट से बाहर निकलने पर SIGINT को प्रक्रिया में आगे नहीं भेजा जाएगा।

मैंने disownसीधे टर्मिनल में कमांड का उपयोग किया है , हालाँकि, बाश में, disownSIGINT को आगे भेजे जाने से नहीं रोकता है। इस स्क्रिप्ट का उद्देश्य एक एकल आह्वान के साथ ओपनकाड और फिर जीडीबी शुरू करना है। चूंकि स्क्रिप्ट कभी भी बाहर नहीं निकलती है (यह gdb चल रही है) SIGINT को अभी भी gdb से ओपनकाड के लिए भेजा जाता है जो एक समस्या है क्योंकि SIGINT को gdb में हाल्ट कमांड के रूप में उपयोग किया जाता है।

टर्मिनल में यह कुछ इस तरह दिखेगा:

$ openocd &    # run openocd demonized
$ disown $!    # disown last pid
$ gdb          # invoke GDB

जब इस क्रम में टर्मिनल पर आमंत्रित किया जाता है, तो SIGINT को gdb से ओपनोकैड में पारित नहीं किया जाता है। हालाँकि यदि यह एक ही आह्वान बैश स्क्रिप्ट में था, SIGINT पास है।

किसी भी तरह की सहायता का स्वागत किया जाएगा।

ps यह समस्या OS X में है, लेकिन मैं उन टूल्स का उपयोग करने की कोशिश कर रहा हूं जो सभी यूनिक्स टूल्स के लिए पोर्टेबल हैं।


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

1
क्या आप एक उपकरण का उपयोग करने के लिए खुले हैं screen?
एरिक रेनॉफ

जवाबों:


16

बैश स्क्रिप्ट से एक प्रक्रिया को अलग करने के लिए:

nohup ./process &

यदि आप अपनी bash स्क्रिप्ट को SIGINT(ctrl + c), या शेल SIGHUPको उदाहरण के लिए भेजना बंद कर देते हैं , तो प्रक्रिया परेशान नहीं होगी और सामान्य रूप से क्रियान्वित होती रहेगी। stdoutऔर stderrएक लॉग फ़ाइल पर पुनर्निर्देशित किया जाएगा nohup.out:।

यदि आप टर्मिनल में आउटपुट देखने में सक्षम होने के दौरान एक अलग कमांड निष्पादित करना चाहते हैं, तो उपयोग करें tail:

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &

nohupनेकसेरी क्यों है ? क्या अंतर है nohup COMMAND &और COMMAND &अगर आपका लक्ष्य केवल पृष्ठभूमि में कमांड चलाना और टर्मिनल को मुक्त करना है?
जेम्स विर्ज़बा

@JamesWierzba मतभेदों में से एक यह है कि यदि आपको शेल से बाहर निकलने के बाद भी चलाने के लिए कमांड की आवश्यकता है, तो nohup जाने का रास्ता है। वेब में व्यापक व्याख्याएं हैं। उदाहरण के लिए stackoverflow.com/questions/15595374/...
मार्क


4

मुझे जो समाधान मिला, उसमें एनॉन इनग्लोरियन द्वारा लिखित 'डिटैच' नामक एक कार्यक्रम शामिल है और उनकी वेबसाइट से डाउनलोड किया जा सकता है

एक बार संकलित करने के बाद, इसे स्क्रिप्ट में निम्नानुसार इस्तेमाल किया जा सकता है:

$ ./detach -p debug.pid openocd <args> # detach openocd
$ gdb <args>                           # run gdb
$ kill -9 $(cat debug.pid)             # end openocd process
$ rm debug.pid                         # remove file containing process id

यह पहली पंक्ति एक नई प्रक्रिया बनाती है (ओपनोकैड चल रही है) और बाद में उपयोग के लिए प्रक्रिया आईडी को फ़ाइल (डीबग.पिड) में संग्रहीत करती है। यह ओलिवर के उत्तर में दिए अनुसार पिड के लिए समस्या को रोकने से रोकता है। अगले ब्लॉकिंग प्रोग्राम (gdb) से बाहर निकलने पर, पीआईडी ​​को संग्रहीत करने वाली फ़ाइल का उपयोग सीधे अलग की गई प्रक्रिया को मारने के लिए किया जाता है।


पुष्टि कर सकता है, detachचमत्कार करता है।
के रूप में

2

एक सरल और पोर्टेबल समाधान:

echo "openocd" | at now #openocd starts now, but via the at daemon, not the current shell!
pid=$(ps -ef | grep "[o]penocd" | awk '{print $1}')  
echo "openocd is running with pid: $pid"
gdb

कुछ पोर्टेबिलिटी कैविट्स: psविकल्प ओएस पर निर्भर करते हैं! आप के बजाय का एक संस्करण इस्तेमाल कर सकते हैं: { ps -ef || ps aux ;} | grep '[o]penocd | cut -f 1atउपलब्ध नहीं हो सकता (अजीब है, लेकिन ऐसा होता है ...)। $(...)वास्तविक रूप से पुराने शेल की आवश्यकता नहीं है, अन्यथा बैकटिक्स का उपयोग करें।


यह खतरनाक लगता है, अगर एक से अधिक प्रक्रिया एक ही नाम से चल रही हो, या यहां तक ​​कि, अगर किसी अन्य प्रक्रिया में ओपनकाड शब्द हो, तो पिड के लिए ग्रिप करना अप्रत्याशित काम कर सकता है।
ओरियन

1
@orion: मैं विचारों को देने के लिए एक सरल उदाहरण देता हूं, जिन चिंताओं का आप उल्लेख करते हैं, उनसे छुटकारा पाना आसान है: atएक स्क्रिप्ट शुरू की है जो प्रोग्राम लॉन्च करती है और एक फ़ाइल के बजाय अपना पीड आउट देती है, और उसके लिए मुख्य स्क्रिप्ट प्रतीक्षा करें दिखाई देने के लिए फ़ाइल और फिर उसमें से रीड पढ़ें।
ओलिवियर दुलैक

बेशक आपको मेरे (सामान्य रूप से सरल) उदाहरण को grep में awk के अंदर एक परीक्षण के साथ देखना चाहिए, सही कॉलम ($ 8, आमतौर पर) पर (कॉलम आपके ओएस पर निर्भर करता है और ps के संस्करण / विकल्प पर निर्भर करता है)
Olivier Dulac
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.