2009-06-10 21 views
8

मुझे आश्चर्य है कि क्या trap जीएनयू make में लागू करने का कोई तरीका है, जैसा कि BASH में बनाया गया था?मैं जीएनयू में त्रुटियों और बाधाओं को कैसे जा सकता हूं?

यदि उपयोगकर्ता CTRL-C दबाता है, या make स्वयं विफल रहता है (गैर-शून्य निकास), तो मैं एक विशेष लक्ष्य या मैक्रो कॉल करना चाहता हूं।

+0

+1 दिलचस्प प्रश्न के लिए +1, भले ही आप जो भी कर रहे हैं, वह एक बुरा विचार की तरह लगता है। – finnw

उत्तर

2

नहीं जीएनयू मेक सिग्नल हैंडलिंग पहले से ही वांछित होने के लिए बहुत कुछ छोड़ देता है। इसके सिग्नल हैंडलर के भीतर से, यह printf जैसे कार्यों को कॉल करता है जो सिग्नल हैंडलर के भीतर से सुरक्षित नहीं हैं। मैंने इस कारण की समस्याएं देखी हैं, उदाहरण के लिए .DELETE_ON_ERROR नियम हमेशा नहीं चलते हैं यदि stderr को stdout पर रीडायरेक्ट किया गया है।

उदाहरण के लिए, एक CentOS 7.4 बॉक्स पर:

  1. निम्नलिखित Makefile बनाएँ:, vim में

    .DELETE_ON_ERROR: 
    
    foo: 
         touch [email protected] 
         sleep 10 
    
  2. ओपन यह और :make चलाने

  3. यह सो रहा है, वहीं हिट Ctrl - सी

विम/प्रिंट

Press ENTER or type command to continue 
touch foo 
sleep 10 
^C 
shell returned 130 

Interrupt: Press ENTER or type command to continue 

मेक बनाने व्यवधान संकेत भेजा गया था, लेकिन foo अभी भी मौजूद है।

+0

क्या आपके पास कुछ उदाहरण हैं जहां '.DELETE_ON_ERROR' काम नहीं करता है? क्या यह कार्यान्वयन करने में एक बग है? –

+0

@ हकनबाबा विवरण जोड़ा गया। – andrewdotn

1

नहीं। जहाँ तक मुझे पता है कि ऐसी कोई कार्यक्षमता नहीं है।

1

रिटर्न कोड का उत्पादन करता है। जहां तक ​​मैं अभी याद कर सकता हूं, यह सफलता के लिए 0 लौटाता है, असफलता के लिए 2 (कृपया दस्तावेज़ीकरण की जांच करें)। इसलिए, क्या आपके लिए एक शेल स्क्रिप्ट के अंदर लपेटने के लिए पर्याप्त होगा उदाहरण के लिए?

+1

मैं ऐसा कर सकता हूं, लेकिन यदि संभव हो तो इसे टालने का प्रयास कर रहा हूं, यह स्वयं निहित है और मैं इसे इस तरह से रखने के लिए * कोशिश कर रहा हूं। – Cyrus

2

मेक इसका समर्थन नहीं करता है, लेकिन बाश चाल का उपयोग करके आप कुछ इसी तरह पूरा कर सकते हैं।

default: complete 

complete: do_mount 
     echo "Do something here..." 

do_mount: 
     mkdir -p "$(MOUNTPOINT)" 
     (while ps -p $$PPID >/dev/null ; do \ 
       sleep 1 ; \ 
     done ; \ 
     unmount "$(MOUNTPOINT)" \ 
     ) & 
     mount "$(MOUNTSOURCE)" "$(MOUNTPOINT)" -o bind 

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

5

इस समय, जीएनयू के पास मूल समर्थन नहीं है।

वहाँ एक विश्वसनीय वैकल्पिक हल तथापि है:

.PHONY: internal-target external-target 

external-target: 
    bash -c "trap 'trap - SIGINT SIGTERM ERR; <DO CLEANUP HERE>; exit 1' SIGINT SIGTERM ERR; $(MAKE) internal-target" 

internal-target: 
    echo "doing stuff here" 

यह रुकावट, समाप्ति और किसी भी गैर शून्य से बाहर निकलें कोड फैल जाती है।

$(MAKE) पर ध्यान दें ताकि cmdline ओवरराइड हो और विकल्प सबमिट करने के लिए पास हो जाएं।

जाल पर:

  • (साथ -) स्पष्ट जाल हैंडलर
  • गैर शून्य बाहर निकलने की स्थिति के साथ सफाई
  • बाहर निकलें है, इसलिए स्वचालन उपकरण निर्माण में विफल रहा है निर्माण रिपोर्ट।

DELETE_ON_ERROR निर्देशिकाओं के लिए काम नहीं करता, तो यह वैध अध्यक्ष एवं प्रबंध निदेशक के साथ <DO CLEANUP HERE> बदलें mktemp -d के बाद सफाई के लिए महत्वपूर्ण है, उदाहरण के

के लिए।

+0

आपकी गूंज में घोंसला उद्धरण के अलावा, जो निश्चित रूप से गैरकानूनी हैं, यह कम से कम काम करने के लिए काम नहीं करता है। इसका उपयोग कैसे किया जाता है? मान लीजिए कि मेरे मेकफ़ाइल में नींद और स्पर्श के साथ केवल एक लक्ष्य था, जैसे @andrewdotn उदाहरण (अनदेखा .DELETE_ON_ERROR), आप इस वर्कअराउंड का उपयोग करने के लिए इसे कैसे संशोधित करेंगे? – Davide

+0

कृपया संपादन देखें। गूंज "यहाँ सामान कर रहा है" नींद/स्पर्श होगा। क्या क्लीनअप यहां कुछ ऐसा होगा, जिसे आपने दबाया है ctrl-c – kevinf

3

जो बुनियादी मामलों के लिए काफी अच्छा लगता है @ kevinf के जवाब का एक सरलीकृत संस्करण:

run: 
    bash -c "trap 'docker-compose down' EXIT; docker-compose up --build" 

(यह उदाहरण एक कारण के लिए है: docker-compose up कहना है

जब आदेश बाहर निकलता है, सभी कंटेनर बंद कर दिए गए हैं।

लेकिन यह rm रोकथाम contai नहीं है docker run --rm जैसे ners, ताकि आप उन्हें docker ps -a के साथ देख सकें।)

+0

मुझे अभी भी 'लक्ष्य के लिए नुस्खा' रन 'असफल' दिखाई देता है ... बनाना: *** [run] जब मैं इसे आज़माता हूं तो चलाएं, और लक्ष्य लक्ष्य नहीं करता है 'डॉकर-कंपोज़ डाउन' कमांड चलाएं। (मेरे पास इस उत्तर में वर्णित सटीक उपयोग केस है।) – ely