क्या ईआरआर सिग्नल को किस लाइन से भेजा जाना संभव है?
हां, LINENO
और BASH_LINENO
चरों को विफलता की रेखा और उस तक पहुंचने वाली रेखाओं के लिए उपयोगी माना जाता है।
या शायद मैं यह सब गलत कर रहा हूँ?
नहीं, बस -q
grep के साथ लापता विकल्प ...
echo hello | grep -q "asdf"
... -q
विकल्प के लिए और के लिए grep
वापस आ जाएगी । और बैश में यह नहीं है ...0
true
1
false
trap
Trap
trap "_func" ERR
... मुझे एक देशी समाधान चाहिए ...
यहां एक ट्रॉपर है कि हां उन चीजों को डिबग करने के लिए उपयोगी हो सकता है जिनके पास थोड़ा और अधिक चक्रीय जटिलता है ...
failure.sh
## Outputs Front-Mater formatted failures for functions not returning 0
## Use the following line after sourcing this file to set failure trap
## trap 'failure "LINENO" "BASH_LINENO" "${BASH_COMMAND}" "${?}"' ERR
failure(){
local -n _lineno="${1:-LINENO}"
local -n _bash_lineno="${2:-BASH_LINENO}"
local _last_command="${3:-${BASH_COMMAND}}"
local _code="${4:-0}"
## Workaround for read EOF combo tripping traps
if ! ((_code)); then
return "${_code}"
fi
local _last_command_height="$(wc -l <<<"${_last_command}")"
local -a _output_array=()
_output_array+=(
'---'
"lines_history: [${_lineno} ${_bash_lineno[*]}]"
"function_trace: [${FUNCNAME[*]}]"
"exit_code: ${_code}"
)
if [[ "${#BASH_SOURCE[@]}" -gt '1' ]]; then
_output_array+=('source_trace:')
for _item in "${BASH_SOURCE[@]}"; do
_output_array+=(" - ${_item}")
done
else
_output_array+=("source_trace: [${BASH_SOURCE[*]}]")
fi
if [[ "${_last_command_height}" -gt '1' ]]; then
_output_array+=(
'last_command: ->'
"${_last_command}"
)
else
_output_array+=("last_command: ${_last_command}")
fi
_output_array+=('---')
printf '%s\n' "${_output_array[@]}" >&2
exit ${_code}
}
... और फ़ंक्शन ट्रेसिंग के लिए उपरोक्त जाल सेट करने के लिए सूक्ष्म अंतरों को उजागर करने के लिए एक उदाहरण उपयोग स्क्रिप्ट भी ...
example_usage.sh
#!/usr/bin/env bash
set -E -o functrace
## Optional, but recommended to find true directory this script resides in
__SOURCE__="${BASH_SOURCE[0]}"
while [[ -h "${__SOURCE__}" ]]; do
__SOURCE__="$(find "${__SOURCE__}" -type l -ls | sed -n 's@^.* -> \(.*\)@\1@p')"
done
__DIR__="$(cd -P "$(dirname "${__SOURCE__}")" && pwd)"
## Source module code within this script
source "${__DIR__}/modules/trap-failure/failure.sh"
trap 'failure "LINENO" "BASH_LINENO" "${BASH_COMMAND}" "${?}"' ERR
something_functional() {
_req_arg_one="${1:?something_functional needs two arguments, missing the first already}"
_opt_arg_one="${2:-SPAM}"
_opt_arg_two="${3:0}"
printf 'something_functional: %s %s %s' "${_req_arg_one}" "${_opt_arg_one}" "${_opt_arg_two}"
## Generate an error by calling nothing
"${__DIR__}/nothing.sh"
}
## Ignoring errors prevents trap from being triggered
something_functional || echo "Ignored something_functional returning $?"
if [[ "$(something_functional 'Spam!?')" == '0' ]]; then
printf 'Nothing somehow was something?!\n' >&2 && exit 1
fi
## And generating an error state will cause the trap to _trace_ it
something_functional '' 'spam' 'Jam'
ऊपर जहां बैश संस्करण 4+ पर परीक्षण किया गया है, इसलिए यदि चार से पहले के संस्करणों के लिए कुछ आवश्यक है, तो एक टिप्पणी छोड़ दें, या चार के न्यूनतम संस्करण के साथ सिस्टम पर विफलताओं को विफल करने के लिए एक समस्या खोलें ।
मुख्य takeaways हैं ...
set -E -o functrace
trap 'failure "LINENO" "BASH_LINENO" "${BASH_COMMAND}" "${?}"' ERR
सिंगल कॉट्स का उपयोग फंक्शन कॉल के चारों ओर किया जाता है और डबल कोट्स व्यक्तिगत तर्कों के आसपास होते हैं
वर्तमान मानों के बजाय संदर्भ LINENO
और BASH_LINENO
पारित किए जाते हैं, हालांकि इसे जाल से जुड़े बाद के संस्करणों में छोटा किया जा सकता है, जैसे कि अंतिम विफलता रेखा इसे आउटपुट में बनाती है
पहले BASH_COMMAND
और बाहर निकलने की स्थिति ( $?
) के मान पारित किए जाते हैं, पहले एक त्रुटि वापस करने वाली कमांड प्राप्त करने के लिए, और दूसरा यह सुनिश्चित करने के लिए कि ट्रैप गैर-त्रुटि स्थितियों पर ट्रिगर नहीं होता है
और जब कुछ लोग असहमत हो सकते हैं, तो मुझे लगता है कि एक आउटपुट एरे का निर्माण करना आसान है और प्रत्येक एलाइन तत्व को प्रिंट करने के लिए प्रिंटफ का उपयोग करना चाहिए।
printf '%s\n' "${_output_array[@]}" >&2
... >&2
अंत में बिट भी त्रुटियों का कारण बनता है जहां उन्हें जाना चाहिए (मानक त्रुटि), और बस त्रुटियों को कैप्चर करने की अनुमति देता है ...
## ... to a file...
some_trapped_script.sh 2>some_trapped_errros.log
## ... or by ignoring standard out...
some_trapped_script.sh 1>/dev/null
जैसा कि स्टैक ओवरफ्लो पर इन और अन्य उदाहरणों द्वारा दिखाया गया है , उपयोगिताओं में निर्मित डिबगिंग सहायता का निर्माण करने के बहुत सारे तरीके हैं।
bashdb
। ऐसा लगता है कि पहले तर्क मेंtrap
उन चर शामिल हो सकते हैं जिनका वांछित संदर्भ में मूल्यांकन किया गया है। इसलिएtrap 'echo $LINENO' ERR'
काम करना चाहिए।