एक प्रक्रिया को मारें और इसे लिनक्स में 0 पर लौटने के लिए मजबूर करें?


16

लिनक्स वातावरण में, मैं एक प्रक्रिया को एक किल सिग्नल कैसे भेज सकता हूं, जबकि यह सुनिश्चित करना कि उस प्रक्रिया से लौटा हुआ निकास कोड 0 है? क्या मुझे इसके लिए कुछ फैंसी जीडीबी जादू करना होगा, या क्या मैं एक फैंसी किल सिग्नल हूं जिससे मैं अनजान हूं?

परीक्षण का मामला:

cat; echo $?

killall cat

विभिन्न किल सिग्नल की कोशिश करने से केवल 129, 137 और 143 जैसे अलग-अलग रिटर्न सिग्नल मिलते हैं। मेरा लक्ष्य एक प्रक्रिया को मारना है, जो एक स्क्रिप्ट चलती है, लेकिन स्क्रिप्ट को लगता है कि यह सफल रहा।

जवाबों:


20

आप GDB और प्रक्रिया ID का उपयोग करके प्रक्रिया से जुड़ सकते हैं और फिर तर्क के रूप में callकमांड जारी exit(0)कर सकते हैं।

callआपको रनिंग प्रोग्राम के भीतर फ़ंक्शन को कॉल करने की अनुमति देता है। कॉलिंग exit(0)0 के रिटर्न कोड के साथ बाहर निकलता है।

gdb -p <process name>
....
.... Gdb output clipped
(gdb) call exit(0)

Program exited normally.

एक-लाइन टूल के रूप में:

gdb --batch --eval-command 'call exit(0)' --pid <process id>

यह काम नहीं करेगा यदि प्रोग्राम उपयोग नहीं करता है (g) libc, उदाहरण के लिए असेंबली में लिखा गया प्रोग्राम No symbol table is loaded. Use the "file" command:। हालांकि यह अत्यधिक संभावना नहीं है।
क्रिस्टियन सियुपिटु

एक रूबी स्क्रिप्ट पर काम किया :-D
मिखाइल

1
@CristianCiupitu उस समस्या के आसपास एक तरीका है। अगली सिस्टम कॉल में प्रवेश करने पर, संबंधित प्रोग्राम को तर्क के _exitसाथ सिस्टम कॉल को कॉल करने के लिए संबंधित रजिस्टर को संशोधित करें 0। यह किसी भी प्रक्रिया पर काम करेगा जो केवल सीपीयू चक्रों को लूप करना और जलाना नहीं है। यदि प्रक्रिया अनन्त लूप में अटकने के लिए नहीं होती है, तो आप अभी भी उसी दृष्टिकोण का उपयोग कर सकते हैं यदि आप इसके निष्पादन योग्य में कहीं आवश्यक निर्देश पा सकते हैं और वहां निर्देश सूचक को इंगित कर सकते हैं।
कास्परड

@ मिखाइल ने "रूबी स्क्रिप्ट" पर काम किया क्योंकि जीडीबी माणिक दुभाषिया प्रक्रिया से जुड़ा था, जिसका द्विआधारी ग्लिबक के साथ जुड़ा हुआ था।
डैनियल

@kasperd, हाँ, मैं हालांकि, लेकिन अधिक सटीक निर्देश अच्छा होगा।
क्रिस्टियन सियुपिटु

8

जब शेल SIGCHLDइसे पकड़ता है तो बिना शर्त के रिटर्न वैल्यू को गैर-शून्य मान पर उचित रूप से सेट करता है, इसलिए इसके लिए स्क्रिप्ट या शेल के संशोधन की आवश्यकता होगी।


3

मुझे यकीन नहीं है, लेकिन यह 0 के साथ बाहर निकल जाएगा यदि कोई भी सूचीबद्ध संकेत प्राप्त होता है। आप एक फ़ंक्शन कॉल करने सहित अन्य क्रियाएं कर सकते हैं, आदि।

#!/bin/bash 
trap 'exit 0' SIGINT SIGQUIT SIGTERM

3

इस एक-लाइनर ने मेरे लिए काम किया:

/bin/bash -c '/usr/bin/killall -q process_name; exit 0'

मुझे नहीं लगता कि आपने प्रश्न को समझा। कोई रास्ता नहीं है, उस आदेश को हासिल करने जा रहा है जो कि पूछा जा रहा था। यह वही है जो मुझे आपकी आज्ञा का उपयोग करने से मिला $ cat; echo $? Terminated 143:।
कास्परड

2
@ लिंडन थॉमस आपके कोड को यहां दिखाया गया है, वास्तव में रिटर्न 0. करता है। हालांकि जो प्रक्रिया_नाम मारा गया था वह 0 नहीं लौटा है, जो ओपी चाहता था।
डैनियल

2

थोड़ा हैकी तरीका है, लेकिन ..

SIGCHLD हैंडलर को ओवरराइड करते हुए, आप अपनी प्रक्रिया के लिए एक आवरण बना सकते हैं। उदाहरण के लिए:

#!/bin/bash
set -o monitor
trap 'exit(0)' CHLD
/some/dir/yourcommand

उसके बाद आप अपनी स्क्रिप्ट को अपनी प्रक्रिया के बजाय इस रैपर को $ PATH में डालकर और उसी नाम पर नाम बदलकर बना सकते हैं।

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