2012-03-27 15 views
55

मैं उपयोग कर रहा था मेरी पार्टी कार्यों में "बाहर निकलने के 1" बयान पूरी स्क्रिप्ट समाप्त करने के लिए और यह ठीक काम किया:क्या कोई बैश फ़ंक्शन लिखने का कोई तरीका है जो पूरे निष्पादन को रोकता है, इससे कोई फर्क नहीं पड़ता कि इसे कैसे कहा जाता है?

function func() 
{ 
    echo "Goodbye" 
    exit 1 
} 
echo "Function call will abort" 
func 
echo "This will never be printed" 

लेकिन तब मुझे एहसास हुआ कि यह काम जब की तरह कहा जाता है ऐसा नहीं करता है:

res=$(func) 

मैं समझता हूँ कि मैं एक subshell बनाया है और "बाहर निकलने के 1" कि subshell और नहीं प्राथमिक एक ....

लेकिन रोकता वहाँ एक रास्ता एक समारोह जो पूरे निष्पादन रोकता लिखने के लिए है, कोई फर्क नहीं पड़ता कैल कैसा है एलईडी? मुझे केवल वास्तविक वापसी मूल्य (फ़ंक्शन द्वारा प्रतिबिंबित) प्राप्त करने की आवश्यकता है।

उत्तर

64

आप कर सकता है क्या, शीर्ष स्तर खोल रजिस्टर TERM संकेत बाहर निकलने के लिए के लिए, और उसके बाद शीर्ष स्तर खोल करने के लिए एक TERM भेज है:

#!/bin/bash 
trap "exit 1" TERM 
export TOP_PID=$$ 

function func() 
{ 
    echo "Goodbye" 
    kill -s TERM $TOP_PID 
} 

echo "Function call will abort" 
echo $(func) 
echo "This will never be printed" 

तो, अपने कार्य एक TERM संकेत वापस शीर्ष स्तर खोल, जो पकड़ा जाता है करने के लिए भेजता है और प्रदान की कमांडरों का उपयोग कर नियंत्रित किया डी, इस मामले में, "exit 1"

+1

मैं सी 'सेटिड()' फ़ंक्शन के बारे में सोच रहा था, लेकिन यह बिल्कुल वैसे ही काम नहीं करता है। 'Setid' कमांड का उपयोग न करने के लिए अपडेट किया गया है, क्योंकि हमें एक नई प्रक्रिया शुरू करने की आवश्यकता होगी। – FatalError

+2

काम करता है।फ़ंक्शन घोंसले का कोई भी स्तर, कोई प्रवाह ... बस काम करता है। – LiMar

+0

क्या यह सामान्य तर्क() फ़ंक्शन को बाहर करना संभव है जो पहले तर्क के कोड का उपयोग कर बाहर निकलता है, उदा। 'abort 2'' kill' से पहले 'जाल' निकास 2 "TERM' करेगा? –

26

आप set -e जो exits if a command exits with a non-zero status उपयोग कर सकते हैं:

set -e 
func 
set +e 

या वापसी मान हड़पने:

(func) || exit $? 
+1

दिलचस्प बात यह है कि मैं एक समाधान देखता हूं। मुख्य स्क्रिप्ट में "सेट-ए" किसी भी फ़ंक्शन को पूरे निष्पादन को निरस्त करने के लिए 1 (या इसके साथ बाहर निकलने) का कारण बनता है। दुर्भाग्य से "सेट-ए" बहुत सारे व्यवहार में परिवर्तन करता है और मैं इसका उपयोग नहीं कर सकता। – LiMar

+0

आपको संख्यात्मक तुलना के लिए (()) का उपयोग करना चाहिए। [] -gt, -eq, आदि के अंदर उपयोग किया जाना चाहिए। – jordanm

+10

या यहां तक ​​कि 'res = $ (func) || बाहर निकलें ' –

0

एक बच्चा प्रक्रिया परोक्ष बंद करने के लिए माता-पिता की प्रक्रिया के लिए मजबूर नहीं कर सकते। आपको किसी प्रकार की सिग्नलिंग तंत्र का उपयोग करने की आवश्यकता है। विकल्प एक विशेष वापसी मान, या शायद kill के साथ कुछ संकेत भेजने,

function child() { 
    local parent_pid="$1" 
    local other="$2" 
    ... 
    if [[ $failed ]]; then 
     kill -QUIT "$parent_pid" 
    fi 
} 
0

की तरह कुछ शामिल हो सकता है लेकिन वहाँ एक तरह से एक समारोह जो पूरे निष्पादन को रोकता है कोई फर्क नहीं पड़ता कि यह कैसे कहा जाता है लिखने के लिए है?

सं

मैं सिर्फ असली वापसी मान (समारोह से गूँजती) प्राप्त करने के लिए की जरूरत है।

आप कर सकते हैं

res=$(func) 
echo $?