से बाहर निकलने की स्थिति के लिए जांच कर रहा है मुझे एक समस्या है कि बहु-पाइप कमांड श्रृंखला में एक निश्चित कमांड ने त्रुटि डाली है या नहीं। आमतौर पर यह जांचना मुश्किल नहीं है लेकिन न तो set -o pipefail
और न ही ${PIPESTATUS[@]}
मेरे मामले में काम करता है। सेटअप इस तरह है:बैश: मल्टी-पाइप कमांड चेन
cmd="$snmpcmd $snmpargs $agent $oid | grep <grepoptions> for_stuff | cut -d',' f$fields | sed 's/ubstitute/some_other_stuff/g'"
नोट -1: कमांड का परीक्षण पूरी तरह से किया गया था और पूरी तरह से काम करता है।
अब, मैं उस आदेश के आउटपुट को procdata
नामक सरणी में संग्रहीत करना चाहता हूं। इस प्रकार, मैंने किया था:
declare -a procdata
procdata=($(eval $cmd))
नोट -2: क्योंकि अन्यथा $snmpcmd
एक invalid option -- <grepoption>
त्रुटि क्योंकि <grepoption>
एक $snmpcmd
विकल्प स्पष्ट रूप से नहीं है जो कोई मतलब नहीं है के साथ फेंकता eval
आवश्यक है। इस चरण में मैं इसे $snmpcmd
के साथ एक बग मानता हूं लेकिन यह एक और शो है ...
यदि कोई त्रुटि उत्पन्न होती है, तो procdata
खाली हो जाएगा। हालांकि, यह दो अलग-अलग कारणों से खाली हो सकता है: या तो $snmpcmd
(उदा। टाइमआउट) को निष्पादित करते समय त्रुटि हुई या grep
यह नहीं ढूंढ सका कि वह क्या ढूंढ रहा था। समस्या यह है कि, मुझे इन दो मामलों के बीच अंतर करने और उन्हें अलग से संभालने में सक्षम होना चाहिए।
इस प्रकार, set -o pipefail
कोई विकल्प नहीं है क्योंकि यह किसी भी त्रुटि का प्रचार करेगा और मैं अंतर नहीं कर सकता कि पाइप का कौन सा हिस्सा असफल रहा। दूसरी ओर echo ${PIPESTATUS[@]}
procdata=($(eval $cmd))
के बाद हमेशा 0
है, भले ही मेरे पास कई पाइप हैं!? फिर भी अगर मैं तुरंत कमांड को प्रॉम्प्ट पर निष्पादित करता हूं और तुरंत echo ${PIPESTATUS[@]}
पर कॉल करता हूं, तो यह सभी पाइपों के बाहर निकलने की स्थिति को सही तरीके से देता है।
मुझे पता है कि मैं त्रुटि स्ट्रीम को बाध्य करने के लिए बाध्य कर सकता हूं लेकिन मुझे यह देखने के लिए हेरिस्टिक विधियों का उपयोग करना होगा कि procdata
में तत्व वैध या त्रुटि संदेश हैं और मैं झूठी सकारात्मक प्राप्त करने का जोखिम चलाता हूं। मैं /dev/null
पर पाइप स्टडआउट भी पा सकता हूं और केवल त्रुटि स्ट्रीम को कैप्चर कर सकता हूं और जांच सकता हूं कि ${#procdata[@]} -eq 0
है या नहीं। लेकिन मुझे वास्तविक डेटा प्राप्त करने के लिए कॉल दोहराना होगा और पूरा आदेश समय महंगा होगा (सीए 3-5)। मैं इसे दो बार फोन नहीं करना चाहता। या मैं त्रुटियों को लिखने के लिए एक अस्थायी फ़ाइल का उपयोग कर सकता हूं लेकिन मैं फ़ाइलों को बनाने/हटाने के ऊपरी हिस्से के बिना इसे करूंगा।
कोई विचार मैं बैश में यह काम कैसे कर सकता हूं?
धन्यवाद
पुनश्च:
$ echo $BASH_VERSION
4.2.37(1)-release
कह मैं एक ही सोचा था द्वारा
PIPESTATUS
सरणी। दुर्भाग्यवश यह काम नहीं करता है लेकिन मुझे यकीन नहीं है कि क्यों। मैं सटीक आदेश पोस्ट करता हूं क्योंकि मुझे स्पष्ट दिखाई नहीं दे रहा है: – user3040975'स्थानीय cmdargs =" - CHF, -m $ mibs -v $ snmpver -c $ समुदाय $ एजेंट "; स्थानीय procdatacmd = "$ tblcmd $ cmdargs $ proc_table"; procdatacmd + = "| कट-डी ',' -एफ $ फ़ील्ड | grep -we -e | सॉर्ट | uniq -c | sed's/^ * \ | \" // g; s//,/g ' ; echo $ {PIPESTATUS [@]} "'। फिर मैं करता हूं: 'घोषित करें- एक procdata = ($ (head -n -1 <<< $ procdatacmd))। आउटपुट खाली है ... बस कुछ भी नहीं। और एजेंट पर चल रहे हैं और चल रहे हैं। क्या ... –
user3040975
@ user3040975 आप उपरोक्त पंक्ति में किसी भी कमांड को _running_ प्रतीत नहीं करते हैं। – devnull