पर आधारित शैल स्क्रिप्ट से बाहर निकलें मेरे पास एक शेल स्क्रिप्ट है जो कई कमांड निष्पादित करती है। यदि कोई भी आदेश गैर-शून्य निकास कोड से बाहर निकलता है तो मैं शेल स्क्रिप्ट से बाहर कैसे निकल सकता हूं?प्रक्रिया निकास कोड
उत्तर
प्रत्येक आदेश के बाद, बाहर निकलने के कोड हो सकता है $?
वैरिएबल में मिला है ताकि आपके पास कुछ ऐसा हो:
ls -al file.ext
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
आप के बाद से $?
केवल आप पाइप में अंतिम तत्व की वापसी कोड देता है तो, कोड में पाइप्ड आदेशों की सावधान रहना चाहिए:
ls -al file.ext | sed 's/^/xx: /"
त्रुटि कोड नहीं होगा अगर फाइल नहीं करता है ' टी मौजूद है (क्योंकि sed
पाइपलाइन का हिस्सा वास्तव में काम करता है, 0 लौटा रहा है)।
bash
खोल वास्तव में एक सरणी प्रदान करता है जो उस मामले में सहायता कर सकता है, जो कि PIPESTATUS
है।
pax> false | true ; echo ${PIPESTATUS[0]}
1
ध्यान दें कि यह आप false
आदेश, नहीं पूरे पाइप लाइन का परिणाम हो रही है: यह सरणी पाइपलाइन घटकों से प्रत्येक के लिए एक तत्व है, कि तुम ${PIPESTATUS[0]}
की तरह अलग-अलग उपयोग कर सकते हैं नहीं है। तुम भी कार्रवाई करने के लिए पूरी सूची प्राप्त कर सकते हैं आप मनचाहे ढंग से:
true | true | false | true | false
rcs=${PIPESTATUS[*]}; rc=0; for i in ${rcs}; do rc=$(($i > $rc ? $i : $rc)); done
echo $rc
यह माध्यम से चला जाता:
pax> false | true | false; echo ${PIPESTATUS[*]}
1 0 1
आप, आप की तरह कुछ इस्तेमाल कर सकते हैं एक पाइप लाइन से सबसे बड़ी त्रुटि कोड प्राप्त करना चाहता है तो बदले में PIPESTATUS
तत्वों में से प्रत्येक, इसे rc
में संग्रहीत करता है यदि यह पिछले rc
मान से अधिक था।
पोर्टेबल कोड की केवल एक पंक्ति में वही सुविधा: 'ls -al file.ext || $ से बाहर निकलें? '([[]] पोर्टेबल नहीं है) – MarcH
मार्क, मुझे लगता है कि आप पाएंगे कि' [[]] '' bash' में सुंदर पोर्टेबल है, जो प्रश्न टैग किया गया है :-) आश्चर्यजनक रूप से पर्याप्त है, 'ls'' command.com' में काम नहीं करता है, इसलिए यह पोर्टेबल नहीं है, विशेष रूप से मुझे पता है, लेकिन यह आपके द्वारा प्रस्तुत तर्क का एक ही प्रकार है। – paxdiablo
मुझे पता है कि यह प्राचीन है, लेकिन यह ध्यान दिया जाना चाहिए कि आप पहली कमांड के लिए सरणी 'PIPESTATUS' (यानी, '$ {PIPESTATUS [0]}' के माध्यम से पाइप में आदेशों का निकास कोड प्राप्त कर सकते हैं,' $ { PIPESTATUS [1]} 'दूसरे के लिए, या' $ {PIPESTATUS [*]} 'सभी निकास स्टैटी की एक सूची के लिए। – DevSolar
बैश में यह आसान है, बस उन्हें एक साथ बाँध & & साथ:
command1 && command2 && command3
तुम भी नेस्टेड उपयोग कर सकते हैं निर्माण करता है, तो:
if command1
then
if command2
then
do_something
else
exit
fi
else
exit
fi
"set -e
" शायद ऐसा करने का सबसे आसान तरीका है। बस अपने कार्यक्रम में किसी भी आदेश से पहले इसे डाल दें।
यह क्या करता है? कृपया दस्तावेज़ों के लिए कोई लिंक कृपया? –
@SwaroopCH 'set -e' आपकी स्क्रिप्ट निरस्त हो जाएगी यदि आपकी स्क्रिप्ट में कोई भी आदेश त्रुटि स्थिति से बाहर निकलता है और आपने इस त्रुटि को संभाल नहीं लिया है। – Andrew
यदि आप $ के साथ काम करना चाहते हैं, तो आपको $ प्रत्येक के बाद प्रत्येक कमांड के बाद इसे जांचना होगा? प्रत्येक आदेश बाहर निकलने के बाद अद्यतन किया जाता है। इसका अर्थ यह है कि यदि आप पाइपलाइन निष्पादित करते हैं, तो आपको पाइपलाइन में अंतिम प्रक्रिया का एक्ज़िट कोड प्राप्त होगा।
एक और दृष्टिकोण यह करने के लिए है:
set -e
set -o pipefail
आप खोल स्क्रिप्ट के शीर्ष पर इस डालें, तो वह पार्टी की तरह दिखता है आप के लिए इस का ख्याल रखना होगा। जैसा कि पिछले पोस्टर ने नोट किया था, "सेट-ए" किसी भी साधारण कमांड पर किसी त्रुटि के साथ बाहर निकलने के लिए बाश का कारण बन जाएगा। "सेट-पाइपफेल" एक पाइपलाइन में किसी भी कमांड पर त्रुटि के साथ बाहर निकलने के लिए बाश का कारण बन जाएगा।
इस समस्या पर थोड़ी अधिक चर्चा के लिए here या here देखें। Here सेट बिल्टिन पर बैश मैनुअल अनुभाग है।
यह वास्तव में शीर्ष उत्तर होना चाहिए: यह 'PIPESTATUS' का उपयोग करना और हर जगह निकास कोडों की जांच करना बहुत आसान है। – candu
'#!/Bin/bash -e' एक शेल स्क्रिप्ट शुरू करने का एकमात्र तरीका है। आप हमेशा 'foo || जैसी चीजों का उपयोग कर सकते हैं handle_error $? 'अगर आपको वास्तव में बाहर निकलने की स्थिति की जांच करने की आवश्यकता है। –
यदि आप किसी भी पैरामीटर के साथ बैश में बाहर निकलें कॉल करते हैं, तो यह अंतिम आदेश के निकास कोड को वापस कर देगा। पिछला कमांड विफल होने पर, या बैश के साथ संयोजित केवल बाहर निकलने का आह्वान करना चाहिए। लेकिन मैंने इसका परीक्षण नहीं किया है।
command1 || exit; command2 || exit;
बैश चरम $ में अंतिम आदेश के निकास कोड को भी संग्रहीत करेगा?
:
# this will trap any errors or commands with non-zero exit status
# by calling function catch_errors()
trap catch_errors ERR;
#
# ... the rest of the script goes here
#
function catch_errors() {
# do whatever on errors
#
#
echo "script aborted, because of errors";
exit 0;
}
शायद "बाहर निकलें" नहीं होना चाहिए, क्योंकि इससे सफलता का संकेत मिलता है। – nobar
exit_code = $?; गूंज "त्रुटियों के कारण, छोड़ा गया स्क्रिप्ट"; बाहर निकलें $ exit_code – RaSergiy
@ एचएएल 9 001 क्या आपके पास इसका सबूत है? आईबीएम दस्तावेज [अन्यथा कहता है] (http://www.ibm.com/developerworks/aix/library/au-usingtraps/#list4)। –
http://cfaj.freeshell.org/shell/cus-faq-2.html#11
मैं
cmd1|cmd2
प्रथम में
cmd1
के निकास कोड कैसे मिलता है, ध्यान दें किcmd1
बाहर निकलें कोड गैर-शून्य हो सकता है और अभी भी त्रुटि नहीं है। यहcmd | head -1
आप
cmd1
, की एक 141 (या ksh93 साथ 269) से बाहर निकलें स्थिति का निरीक्षण कर सकते हैं में उदाहरण के लिए होता है, लेकिन क्योंकिcmd
एक SIGPIPE संकेत द्वारा बाधित किया गया था जबhead -1
एक पंक्ति को पढ़ने के बाद समाप्त हो गया।एक पाइप लाइन
cmd1 | cmd2 | cmd3
एक के तत्वों में से बाहर निकलने की स्थिति जानने के लिए। zsh के साथ:
निकास कोड पाइपस्टैटस विशेष सरणी में प्रदान किए जाते हैं।
cmd1
बाहर निकलने के कोड,$pipestatus[1]
में है$pipestatus[3]
मेंcmd3
बाहर निकलें कोड है, ताकि$?
हमेशा$pipestatus[-1]
के समान है।बी। बैश के साथ:
निकास कोड
PIPESTATUS
विशेष सरणी में प्रदान किए जाते हैं।cmd1
बाहर निकलने के कोड,${PIPESTATUS[0]}
में है${PIPESTATUS[2]}
मेंcmd3
बाहर निकलें कोड है, ताकि$?
हमेशा${PIPESTATUS: -1}
के समान है।...
अधिक जानकारी के लिए निम्न link देखते हैं।
[ $? -eq 0 ] || exit $?; # exit for none-zero return code
क्या यह 'निकास $' 'नहीं होना चाहिए? (कोई माता-पिता नहीं)? – malthe
#
#------------------------------------------------------------------------------
# run a command on failure exit with message
# doPrintHelp: doRunCmdOrExit "$cmd"
# call by:
# set -e ; doRunCmdOrExit "$cmd" ; set +e
#------------------------------------------------------------------------------
doRunCmdOrExit(){
cmd="[email protected]" ;
doLog "DEBUG running cmd or exit: \"$cmd\""
msg=$($cmd 2>&1)
export exit_code=$?
# if occured during the execution exit with error
error_msg="Failed to run the command:
\"$cmd\" with the output:
\"$msg\" !!!"
if [ $exit_code -ne 0 ] ; then
doLog "ERROR $msg"
doLog "FATAL $msg"
doExit "$exit_code" "$error_msg"
else
#if no errors occured just log the message
doLog "DEBUG : cmdoutput : \"$msg\""
doLog "INFO $msg"
fi
}
#eof func doRunCmdOrExit
'$ * 'का उपयोग करने के लिए शायद ही कभी कोई कारण है; रिक्त स्थान और वाइल्डकार्ड को संरक्षित करने के लिए '" $ @ "का उपयोग करें। –
मैं यह सोचते हैं उत्तर आप बैश का उपयोग कर रहे हैं, लेकिन अगर यह एक बहुत ही अलग खोल है आप अपनी पोस्ट में निर्दिष्ट कर सकते हैं? –