ट्रैप कमांड का उपयोग करके त्रुटि को कैसे ट्रिगर किया जाए


13

मैं Ubuntu 12.04.2 का उपयोग कर रहा हूं। मैं अपने शेल स्क्रिप्ट में असामान्य या त्रुटि को पकड़ने के लिए "ट्रैप" कमांड का उपयोग करने की कोशिश कर रहा हूं लेकिन मैं "त्रुटि" निकास को मैन्युअल रूप से ट्रिगर करने का भी प्रयास कर रहा हूं।

मैंने 1 से बाहर निकलने की कोशिश की है, लेकिन यह "त्रुटि" सिग्नल को ट्रिगर नहीं करेगा।

#!/bin/bash

func()
{
    exit 1
}

trap "echo hi" INT TERM ERR
func

सुनिश्चित नहीं है कि मैन्युअल रूप से "त्रुटि" निकास सिग्नल को कैसे ट्रिगर किया जाए?

जवाबों:


20

ERRजाल उस कोड को चलाने के लिए नहीं है जब शेल स्वयं एक शून्य-शून्य त्रुटि कोड के साथ बाहर निकलता है, लेकिन जब कोई भी कमांड उस शेल से चलता है जो एक शर्त का हिस्सा नहीं है (जैसे if cmd..., या cmd || ......) एक गैर-शून्य के साथ बाहर निकलता है बाहर निकलने की स्थिति ( set -eशेल से बाहर निकलने के कारणों के समान स्थिति )।

यदि आप गैर-शून्य निकास स्थिति के साथ शेल से बाहर निकलने पर कोड चलाना चाहते हैं, तो आपको EXITइसके बजाय एक जाल जोड़ना चाहिए और $?वहां जांच करनी चाहिए :

trap '[ "$?" -eq 0 ] || echo hi' EXIT

ध्यान दें कि एक फंसे सिग्नल पर, सिग्नल ट्रैप और EXIT ट्रैप दोनों चलाए जाएंगे, इसलिए आप इसे करना चाहते हैं:

unset killed_by
trap 'killed_by=INT;exit' INT
trap 'killed_by=TERM;exit' TERM
trap '
  ret=$?
  if [ -n "$killed_by" ]; then
    echo >&2 "Ouch! Killed by $killed_by"
    exit 1
  elif [ "$ret" -ne 0 ]; then
    echo >&2 "Died with error code $ret"
  fi' EXIT

या $((signum + 128))संकेतों पर बाहर निकलने की स्थिति का उपयोग करने के लिए :

for sig in INT TERM HUP; do
  trap "exit $((128 + $(kill -l "$sig")))" "$sig"
done
trap '
  ret=$?
  [ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"' EXIT

हालांकि ध्यान दें कि SIGINT या SIGQUIT पर सामान्य रूप से बाहर निकलने पर संभावित कष्टप्रद दुष्प्रभाव होते हैं जब आपकी मूल प्रक्रिया एक ऐसा शेल होता है bashजो टर्मिनल रुकावट के प्रतीक्षा और सहकारी निकास हैंडलिंग को लागू करता है । इसलिए, आप अपने माता-पिता को सूचित करने के बजाय उसी संकेत के साथ खुद को मारना सुनिश्चित कर सकते हैं ताकि आप वास्तव में बाधित हो गए थे, और यह कि खुद को बाहर निकालने पर विचार करना चाहिए, अगर यह एक संकेत / हस्ताक्षर प्राप्त हुआ।

unset killed_by
for sig in INT QUIT TERM HUP; do
  trap "exit $((128 + $(kill -l "$sig"))); killed_by=$sig" "$sig"
done
trap '
  ret=$?
  [ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"
  if [ -n "$killed_by" ]; then
    trap - "$killed_by" # reset handler
    # ulimit -c 0 # possibly disable core dumps
    kill -s "$killed_by" "$$"
  else
    exec "$ret"
  fi' EXIT

यदि आप चाहते हैं कि ERRजाल में आग लग जाए, तो बस एक गैर-शून्य निकास स्थिति जैसे falseया के साथ एक कमांड चलाएं test


6

किसी फ़ंक्शन से बाहर निकलने पर स्थिति सेट करने के लिए, रिटर्न से बाहर निकलें का उपयोग करें (यदि फ़ंक्शन बिना गिरता है, तो स्थिति अंतिम निष्पादित स्टेटमेंट की है।) यदि आप प्रश्न के उदाहरण में स्थानापन्न returnकरते हैं exit, तो यह इस तरह काम करेगा। मुझे लगता है कि आपका इरादा था: ईआरआर छद्म संकेत पर जाल को ट्रिगर किया जाएगा और 'हाय' मुद्रित किया जाएगा। अतिरिक्त विचारों के लिए, इसे आज़माएँ:

#!/bin/bash

func()
{
    echo 'in func'
    return 99
    echo 'still in func'
}

trap 'echo "done"' EXIT
trap 'status=$?; echo "error status is $status"; trap - EXIT; exit $status' ERR
func
echo 'returned from func'

आप विभिन्न संशोधनों को आज़मा सकते हैं, जैसे कि 0 लौटाना, ईआरआर ट्रैप पर टिप्पणी करना, ईआरआर हैंडलर के भीतर ईएक्सआईटी ट्रैप को रद्द नहीं करना, ईआरआर हैंडलर से बाहर निकलना या रिटर्न को निकालना और falseफ़ंक में अंतिम विवरण के रूप में डालना ।

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