कई आदेशों की कुशलता से बैश निकास स्थिति की जाँच करना


260

क्या मल्टीपल कमांड्स के लिए पाइपलाइफ के समान कुछ है, जैसे 'ट्राय' स्टेटमेंट लेकिन बैश के भीतर। मैं ऐसा कुछ करना चाहूंगा:

echo "trying stuff"
try {
    command1
    command2
    command3
}

और किसी भी बिंदु पर, यदि कोई कमांड विफल रहता है, तो ड्रॉप आउट करें और उस कमांड की त्रुटि को प्रतिध्वनित करें। मैं ऐसा कुछ नहीं करना चाहता:

command1
if [ $? -ne 0 ]; then
    echo "command1 borked it"
fi

command2
if [ $? -ne 0 ]; then
    echo "command2 borked it"
fi

और इसी तरह ... या कुछ भी:

pipefail -o
command1 "arg1" "arg2" | command2 "arg1" "arg2" | command3

क्योंकि प्रत्येक आज्ञा के तर्क मैं मानता हूं (यदि मैं गलत हूं तो मुझे सुधारो) एक दूसरे के साथ हस्तक्षेप करेंगे। ये दो विधियाँ मुझे बहुत लंबी-चौड़ी और गंदी लगती हैं इसलिए मैं यहाँ अधिक कुशल विधि की अपील कर रहा हूँ।


2
करने के लिए एक नजर डालें अनौपचारिक बैश सख्त मोड : set -euo pipefail
पाब्लो ए

1
@PabloBianchi, set -eएक भयानक विचार है। BashFAQ # 105 में कुछ अनपेक्षित किनारे के मामलों की चर्चा करते हुए देखें, जो इसे पेश करते हैं, और / या विभिन्न गोले '(और शेल संस्करणों') के बीच असंगतता दिखाने वाले तुलनाओं में- inulm.de/~masheck/various/set पर लागू होते हैं। -e
चार्ल्स डफी

जवाबों:


274

आप एक फ़ंक्शन लिख सकते हैं जो आपके लिए कमांड लॉन्च और परीक्षण करता है। मान लें command1और command2पर्यावरण चर हैं जो एक कमांड पर सेट किए गए हैं।

function mytest {
    "$@"
    local status=$?
    if (( status != 0 )); then
        echo "error with $1" >&2
    fi
    return $status
}

mytest "$command1"
mytest "$command2"

32
$*यदि कोई तर्क उनके पास रिक्त स्थान है, तो इसका उपयोग न करें ; "$@"इसके बजाय उपयोग करें । इसी तरह, कमांड $1में उद्धरणों के अंदर रखें echo
गॉर्डन डेविसन

82
इसके अलावा, मैं नाम से बचता हूं testक्योंकि यह एक अंतर्निहित कमांड है।
जॉन कुगेलमैन

1
यह वह विधि है जिसके साथ मैं गया था। ईमानदार होने के लिए, मुझे नहीं लगता कि मैं अपने मूल पद में पर्याप्त स्पष्ट था, लेकिन यह विधि मुझे अपना स्वयं का 'परीक्षण' फ़ंक्शन लिखने की अनुमति देती है, इसलिए मैं तब एक त्रुटि कार्रवाई कर सकता हूं जिसमें मुझे पसंद है कि प्रदर्शन किए गए कार्यों के लिए प्रासंगिक है लिपी। धन्यवाद :)
jwbensley

7
परीक्षण द्वारा लौटाया गया निकास कोड नहीं होगा () हमेशा अंतिम त्रुटि के बाद से 0 की वापसी होती है क्योंकि अंतिम कमांड 'इको' था। आपको $ का मूल्य बचाने की आवश्यकता हो सकती है? प्रथम।
जादूगर

2
यह एक अच्छा विचार नहीं है, और यह बुरे अभ्यास को प्रोत्साहित करता है। के साधारण मामले पर विचार करें ls। यदि आप आह्वान करते हैं ls fooऔर ls: foo: No such file or directory\nसमस्या के बारे में समझने के लिए फार्म का त्रुटि संदेश प्राप्त करते हैं । यदि इसके बजाय आप ls: foo: No such file or directory\nerror with ls\nसुपरफ्लुएंस जानकारी से विचलित हो जाते हैं। इस मामले में, यह तर्क देना काफी आसान है कि सुपरफ्लूइट तुच्छ है, लेकिन यह जल्दी से बढ़ता है। संक्षिप्त त्रुटि संदेश महत्वपूर्ण हैं। लेकिन इससे भी महत्वपूर्ण बात यह है कि इस प्रकार के रैपर भी लेखकों को अच्छी त्रुटि संदेशों से पूरी तरह से बाहर निकलने के लिए प्रोत्साहित करते हैं।
विलियम पर्ससेल

185

"ड्रॉप आउट और एरर इको" का क्या मतलब है? यदि आपका मतलब है कि आप चाहते हैं कि स्क्रिप्ट जल्द से जल्द समाप्त हो जाए तो कोई भी आदेश विफल रहता है, तो बस करें

set -e    # DON'T do this.  See commentary below.

स्क्रिप्ट की शुरुआत में (लेकिन नीचे चेतावनी पर ध्यान दें)। त्रुटि संदेश प्रतिध्वनित करने के लिए परेशान न करें: विफल कमांड को संभालें। दूसरे शब्दों में, यदि आप करते हैं:

#!/bin/sh

set -e    # Use caution.  eg, don't do this
command1
command2
command3

और कमांड 2 विफल हो जाता है, जबकि स्टडर को एक त्रुटि संदेश प्रिंट करते हैं, तो ऐसा लगता है कि आपने जो चाहा है वह हासिल कर लिया है। (जब तक मैं गलत व्याख्या नहीं करता कि आप क्या चाहते हैं!)

एक कोरोलरी के रूप में, आप जो भी कमांड लिखते हैं, उसे अच्छी तरह से व्यवहार करना चाहिए: यह स्टडआउट के बजाय स्टॉडर को त्रुटियों की रिपोर्ट करना चाहिए (प्रश्न में नमूना कोड स्टडआउट में त्रुटियों को प्रिंट करता है) और इसे विफल होने पर गैर-शून्य स्थिति से बाहर निकलना चाहिए।

हालाँकि, मैं अब इसे एक अच्छा अभ्यास नहीं मानता। set -eबैश के विभिन्न संस्करणों के साथ अपने शब्दार्थों को बदल दिया है, और यद्यपि यह एक साधारण स्क्रिप्ट के लिए ठीक काम करता है, बहुत सारे किनारे मामले हैं कि यह अनिवार्य रूप से अनुपयोगी है। (इस तरह की बातों पर विचार करें: set -e; foo() { false; echo should not print; } ; foo && echo ok यहाँ शब्दार्थ कुछ हद तक उचित हैं, लेकिन यदि आप एक फ़ंक्शन में कोड को रिफलेक्टर करते हैं, जो जल्दी समाप्त करने के लिए विकल्प सेटिंग पर निर्भर करता है, तो आप आसानी से काट सकते हैं।) IMO लिखना बेहतर है:

 #!/bin/sh

 command1 || exit
 command2 || exit
 command3 || exit

या

#!/bin/sh

command1 && command2 && command3

1
सलाह दी जाती है कि जबकि यह समाधान सबसे सरल है, यह आपको विफलता पर कोई सफाई नहीं करने देता है।
जोश

6
जाल से सफाई पूरी की जा सकती है। (जैसे बाहर निकलने पर trap some_func 0निष्पादित some_func)
विलियम पर्ससेल

3
यह भी ध्यान दें कि इरिटेक्स (सेट-ई) के शब्दार्थ बैश के विभिन्न संस्करणों में बदल गए हैं, और अक्सर फ़ंक्शन आमंत्रण और अन्य सेटिंग्स के दौरान अप्रत्याशित रूप से व्यवहार करेंगे। मैं अब इसके उपयोग की सलाह नहीं देता। IMO, || exitप्रत्येक कमांड के बाद स्पष्ट रूप से लिखना बेहतर है ।
विलियम पुरसेल

87

मेरे पास स्क्रिप्टिंग फ़ंक्शंस का एक सेट है जिसका उपयोग मैं अपने Red Hat सिस्टम पर बड़े पैमाने पर करता हूं। वे /etc/init.d/functionsहरे [ OK ]और लाल [FAILED]स्थिति संकेतक प्रिंट करने के लिए सिस्टम फ़ंक्शन का उपयोग करते हैं ।

$LOG_STEPSयदि आप लॉग इन करना चाहते हैं तो आप वैरिएबल को लॉग फाइल नाम पर सेट कर सकते हैं।

प्रयोग

step "Installing XFS filesystem tools:"
try rpm -i xfsprogs-*.rpm
next

step "Configuring udev:"
try cp *.rules /etc/udev/rules.d
try udevtrigger
next

step "Adding rc.postsysinit hook:"
try cp rc.postsysinit /etc/rc.d/
try ln -s rc.d/rc.postsysinit /etc/rc.postsysinit
try echo $'\nexec /etc/rc.postsysinit' >> /etc/rc.sysinit
next

उत्पादन

Installing XFS filesystem tools:        [  OK  ]
Configuring udev:                       [FAILED]
Adding rc.postsysinit hook:             [  OK  ]

कोड

#!/bin/bash

. /etc/init.d/functions

# Use step(), try(), and next() to perform a series of commands and print
# [  OK  ] or [FAILED] at the end. The step as a whole fails if any individual
# command fails.
#
# Example:
#     step "Remounting / and /boot as read-write:"
#     try mount -o remount,rw /
#     try mount -o remount,rw /boot
#     next
step() {
    echo -n "$@"

    STEP_OK=0
    [[ -w /tmp ]] && echo $STEP_OK > /tmp/step.$$
}

try() {
    # Check for `-b' argument to run command in the background.
    local BG=

    [[ $1 == -b ]] && { BG=1; shift; }
    [[ $1 == -- ]] && {       shift; }

    # Run the command.
    if [[ -z $BG ]]; then
        "$@"
    else
        "$@" &
    fi

    # Check if command failed and update $STEP_OK if so.
    local EXIT_CODE=$?

    if [[ $EXIT_CODE -ne 0 ]]; then
        STEP_OK=$EXIT_CODE
        [[ -w /tmp ]] && echo $STEP_OK > /tmp/step.$$

        if [[ -n $LOG_STEPS ]]; then
            local FILE=$(readlink -m "${BASH_SOURCE[1]}")
            local LINE=${BASH_LINENO[0]}

            echo "$FILE: line $LINE: Command \`$*' failed with exit code $EXIT_CODE." >> "$LOG_STEPS"
        fi
    fi

    return $EXIT_CODE
}

next() {
    [[ -f /tmp/step.$$ ]] && { STEP_OK=$(< /tmp/step.$$); rm -f /tmp/step.$$; }
    [[ $STEP_OK -eq 0 ]]  && echo_success || echo_failure
    echo

    return $STEP_OK
}

यह शुद्ध सोना है। हालांकि मैं समझता हूं कि स्क्रिप्ट का उपयोग करने के लिए मैं प्रत्येक चरण को पूरी तरह से समझ नहीं पा रहा हूं, निश्चित रूप से मेरे बैश स्क्रिप्टिंग ज्ञान के बाहर, लेकिन मुझे लगता है कि यह कला का काम है।
किंगमिलो

2
क्या इस टूल का कोई औपचारिक नाम है? मुझे इस स्टेप / स्टेप / अगली लॉगिंग की शैली पर एक मैन पेज पढ़ना अच्छा लगेगा
ThorSummoner

ये शेल फ़ंक्शन उबंटू पर अनुपलब्ध प्रतीत होते हैं? मैं इस का उपयोग करने की उम्मीद कर रहा था, कुछ पोर्टेबल-ईश हालांकि
थोरसुमोनर

@ थोरसुमोनर, यह संभावना है क्योंकि उबंटू SysV init के बजाय अपस्टार्ट का उपयोग करता है, और जल्द ही सिस्टमड का उपयोग करेगा। RedHat लंबे समय तक पश्चगामी संगतता बनाए रखता है, यही कारण है कि init.d सामान अभी भी है।
ड्रैगन 788 16

मैंने जॉन के समाधान पर एक विस्तार पोस्ट किया है और इसे उबंटू जैसे गैर-रेडहैट सिस्टम पर उपयोग करने की अनुमति देता है। देखें stackoverflow.com/a/54190627/308145
मार्क थॉमसन

51

इसकी कीमत क्या है, सफलता के लिए प्रत्येक कमांड को जांचने के लिए कोड लिखने का एक छोटा तरीका है:

command1 || echo "command1 borked it"
command2 || echo "command2 borked it"

यह अभी भी थकाऊ है लेकिन कम से कम यह पठनीय है।


इस बारे में नहीं सोचा था, न कि मैं जिस विधि से गया था, लेकिन यह पढ़ने में तेज और आसान है, जानकारी के लिए धन्यवाद :)
jwbensley

3
आदेशों को चुपचाप निष्पादित करने और एक ही चीज को प्राप्त करने के लिए:command1 &> /dev/null || echo "command1 borked it"
मैट बर्न

मैं इस पद्धति का प्रशंसक हूं, क्या OR के बाद कई कमांड निष्पादित करने का कोई तरीका है? कुछ इस तरहcommand1 || (echo command1 borked it ; exit)
AndreasKralj

38

एक विकल्प बस आदेशों को एक साथ &&जोड़ना है ताकि असफल होने वाला पहला व्यक्ति शेष को निष्पादित करने से रोकता है:

command1 &&
  command2 &&
  command3

यह वह सिंटैक्स नहीं है जो आपने प्रश्न में पूछा था, लेकिन यह आपके द्वारा उपयोग किए जाने वाले केस के लिए एक सामान्य पैटर्न है। सामान्य तौर पर आदेशों को मुद्रण विफलताओं के लिए ज़िम्मेदार होना चाहिए ताकि आपको ऐसा मैन्युअल रूप से न करना पड़े (हो सकता है कि -qजब आप उन्हें न चाहते हों तो झंडे के साथ मौन त्रुटियों के लिए हो)। यदि आपके पास इन आदेशों को संशोधित करने की क्षमता है, तो मैं उन्हें विफलता पर चिल्लाने के बजाय उन्हें किसी और चीज़ में लपेटने के बजाय संपादित करूँगा।


ध्यान दें कि आपको करने की आवश्यकता नहीं है:

command1
if [ $? -ne 0 ]; then

आप बस कह सकते हैं:

if ! command1; then

और जब आपको रिटर्न कोड की जांच करने की आवश्यकता होती है, तो इसके बजाय एक अंकगणितीय संदर्भ का उपयोग करें [ ... -ne:

ret=$?
# do something
if (( ret != 0 )); then

34

रनर फ़ंक्शंस बनाने या उपयोग करने के बजाय set -e, trapनिम्न का उपयोग करें :

trap 'echo "error"; do_cleanup failed; exit' ERR
trap 'echo "received signal to stop"; do_cleanup interrupted; exit' SIGQUIT SIGTERM SIGINT

do_cleanup () { rm tempfile; echo "$1 $(date)" >> script_log; }

command1
command2
command3

जाल में लाइन नंबर और कमांड की कमांड लाइन तक पहुंच होती है जो इसे ट्रिगर करता है। चर हैं $BASH_LINENOऔर $BASH_COMMAND


4
यदि आप एक कोशिश ब्लॉक को और भी करीब से नकल करना चाहते हैं, trap - ERRतो "ब्लॉक" के अंत में जाल को बंद करने का उपयोग करें।
गॉर्डन डेविसन

14

निजी तौर पर मैं एक हल्के दृष्टिकोण का उपयोग करना पसंद करता हूं, जैसा कि यहां देखा गया है ;

yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }
asuser() { sudo su - "$1" -c "${*:2}"; }

उदाहरण का उपयोग:

try apt-fast upgrade -y
try asuser vagrant "echo 'uname -a' >> ~/.profile"

8
run() {
  $*
  if [ $? -ne 0 ]
  then
    echo "$* failed with exit code $?"
    return 1
  else
    return 0
  fi
}

run command1 && run command2 && run command3

6
$*यदि कोई तर्क उनके पास रिक्त स्थान है, तो यह न चलें ; "$@"इसके बजाय उपयोग करें । (हालांकि $ * echoकमांड में ठीक है ।)
गॉर्डन डेविसन

6

मैंने लगभग दोषरहित कोशिश की और बैश में कार्यान्वयन को विकसित किया, जिससे आप कोड लिख सकते हैं जैसे:

try 
    echo 'Hello'
    false
    echo 'This will not be displayed'

catch 
    echo "Error in $__EXCEPTION_SOURCE__ at line: $__EXCEPTION_LINE__!"

तुम भी अपने अंदर की कोशिश पकड़ ब्लॉक घोंसला कर सकते हैं!

try {
    echo 'Hello'

    try {
        echo 'Nested Hello'
        false
        echo 'This will not execute'
    } catch {
        echo "Nested Caught (@ $__EXCEPTION_LINE__)"
    }

    false
    echo 'This will not execute too'

} catch {
    echo "Error in $__EXCEPTION_SOURCE__ at line: $__EXCEPTION_LINE__!"
}

कोड मेरे बैश बॉयलरप्लेट / ढांचे का एक हिस्सा है । यह आगे की कोशिश करने के विचार को बढ़ाता है और बैकट्रेस और अपवादों के साथ त्रुटि से निपटने जैसी चीजों को पकड़ता है (साथ ही कुछ अन्य अच्छी विशेषताएं)।

यहाँ वह कोड है जो केवल कोशिश और पकड़ने के लिए जिम्मेदार है:

set -o pipefail
shopt -s expand_aliases
declare -ig __oo__insideTryCatch=0

# if try-catch is nested, then set +e before so the parent handler doesn't catch us
alias try="[[ \$__oo__insideTryCatch -gt 0 ]] && set +e;
           __oo__insideTryCatch+=1; ( set -e;
           trap \"Exception.Capture \${LINENO}; \" ERR;"
alias catch=" ); Exception.Extract \$? || "

Exception.Capture() {
    local script="${BASH_SOURCE[1]#./}"

    if [[ ! -f /tmp/stored_exception_source ]]; then
        echo "$script" > /tmp/stored_exception_source
    fi
    if [[ ! -f /tmp/stored_exception_line ]]; then
        echo "$1" > /tmp/stored_exception_line
    fi
    return 0
}

Exception.Extract() {
    if [[ $__oo__insideTryCatch -gt 1 ]]
    then
        set -e
    fi

    __oo__insideTryCatch+=-1

    __EXCEPTION_CATCH__=( $(Exception.GetLastException) )

    local retVal=$1
    if [[ $retVal -gt 0 ]]
    then
        # BACKWARDS COMPATIBILE WAY:
        # export __EXCEPTION_SOURCE__="${__EXCEPTION_CATCH__[(${#__EXCEPTION_CATCH__[@]}-1)]}"
        # export __EXCEPTION_LINE__="${__EXCEPTION_CATCH__[(${#__EXCEPTION_CATCH__[@]}-2)]}"
        export __EXCEPTION_SOURCE__="${__EXCEPTION_CATCH__[-1]}"
        export __EXCEPTION_LINE__="${__EXCEPTION_CATCH__[-2]}"
        export __EXCEPTION__="${__EXCEPTION_CATCH__[@]:0:(${#__EXCEPTION_CATCH__[@]} - 2)}"
        return 1 # so that we may continue with a "catch"
    fi
}

Exception.GetLastException() {
    if [[ -f /tmp/stored_exception ]] && [[ -f /tmp/stored_exception_line ]] && [[ -f /tmp/stored_exception_source ]]
    then
        cat /tmp/stored_exception
        cat /tmp/stored_exception_line
        cat /tmp/stored_exception_source
    else
        echo -e " \n${BASH_LINENO[1]}\n${BASH_SOURCE[2]#./}"
    fi

    rm -f /tmp/stored_exception /tmp/stored_exception_line /tmp/stored_exception_source
    return 0
}

बेझिझक उपयोग करें, कांटे और योगदान - यह GitHub पर है


1
मैंने रेपो को देखा है और इसे स्वयं उपयोग नहीं किया है, क्योंकि यह मेरे स्वाद के लिए बहुत अधिक जादू है (IMO यह बेहतर है कि पायथन का उपयोग करें यदि किसी को अधिक अमूर्त शक्ति की आवश्यकता है), लेकिन निश्चित रूप से मुझसे बड़ा +1 क्योंकि यह सिर्फ भयानक दिखता है।
अलेक्जेंडर मालाखोव

इस तरह के शब्दों के लिए धन्यवाद @AlexanderMalakhov। मैं "जादू" की मात्रा के बारे में सहमत हूं - यही एक कारण है कि हम फ्रेमवर्क के सरलीकृत 3.0 संस्करण पर विचार कर रहे हैं, जिसे समझना बहुत आसान होगा, डीबग करना, आदि। जीएच पर 3.0 के बारे में एक खुला मुद्दा है, यदि आप अपने विचारों में चिप लगाना चाहते हैं।
niieani

3

क्षमा करें कि मैं पहले उत्तर पर टिप्पणी नहीं कर सकता, लेकिन आपको कमांड को निष्पादित करने के लिए नए उदाहरण का उपयोग करना चाहिए: cmd_output = $ ($ @)

#!/bin/bash

function check_exit {
    cmd_output=$($@)
    local status=$?
    echo $status
    if [ $status -ne 0 ]; then
        echo "error with $1" >&2
    fi
    return $status
}

function run_command() {
    exit 1
}

check_exit run_command

2

के लिए मछली खोल उपयोगकर्ताओं को, जो इस धागे पर ठोकर।

मान लें fooकि एक फ़ंक्शन है जो "रिटर्न" (इको) नहीं करता है, लेकिन यह हमेशा की तरह निकास कोड सेट करता है। फ़ंक्शन को कॉल
करने के $statusबाद जाँच से बचने के लिए , आप कर सकते हैं:

foo; and echo success; or echo failure

और अगर यह एक पंक्ति में फिट होने के लिए बहुत लंबा है:

foo; and begin
  echo success
end; or begin
  echo failure
end

1

जब मैं उपयोग करता sshहूं तो मुझे कनेक्शन समस्याओं और रिमोट कमांड errexit( set -e) मोड में त्रुटि कोड के कारण होने वाली समस्याओं के बीच अंतर करने की आवश्यकता होती है। मैं निम्नलिखित फ़ंक्शन का उपयोग करता हूं:

# prepare environment on calling site:

rssh="ssh -o ConnectionTimeout=5 -l root $remote_ip"

function exit255 {
    local flags=$-
    set +e
    "$@"
    local status=$?
    set -$flags
    if [[ $status == 255 ]]
    then
        exit 255
    else
        return $status
    fi
}
export -f exit255

# callee:

set -e
set -o pipefail

[[ $rssh ]]
[[ $remote_ip ]]
[[ $( type -t exit255 ) == "function" ]]

rjournaldir="/var/log/journal"
if exit255 $rssh "[[ ! -d '$rjournaldir/' ]]"
then
    $rssh "mkdir '$rjournaldir/'"
fi
rconf="/etc/systemd/journald.conf"
if [[ $( $rssh "grep '#Storage=auto' '$rconf'" ) ]]
then
    $rssh "sed -i 's/#Storage=auto/Storage=persistent/' '$rconf'"
fi
$rssh systemctl reenable systemd-journald.service
$rssh systemctl is-enabled systemd-journald.service
$rssh systemctl restart systemd-journald.service
sleep 1
$rssh systemctl status systemd-journald.service
$rssh systemctl is-active systemd-journald.service

1

आप गैर -रेडहैट सिस्टम पर ऊपर दिए गए @ जॉन-कुगेलमैन के भयानक समाधान का उपयोग कर सकते हैं, इस लाइन को अपने कोड में टिप्पणी करके:

. /etc/init.d/functions

फिर, नीचे दिए गए कोड को अंत में पेस्ट करें। पूर्ण प्रकटीकरण: यह सेंटोस 7 से ली गई उपर्युक्त फ़ाइल के प्रासंगिक बिट्स की एक सीधी प्रतिलिपि और पेस्ट है।

MacOS और Ubuntu 18.04 पर परीक्षण किया गया।


BOOTUP=color
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"

echo_success() {
    [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
    echo -n "["
    [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
    echo -n $"  OK  "
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    echo -n "]"
    echo -ne "\r"
    return 0
}

echo_failure() {
    [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
    echo -n "["
    [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
    echo -n $"FAILED"
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    echo -n "]"
    echo -ne "\r"
    return 1
}

echo_passed() {
    [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
    echo -n "["
    [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
    echo -n $"PASSED"
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    echo -n "]"
    echo -ne "\r"
    return 1
}

echo_warning() {
    [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
    echo -n "["
    [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
    echo -n $"WARNING"
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    echo -n "]"
    echo -ne "\r"
    return 1
} 

0

कार्यात्मक तरीके से स्थिति की जांच करना

assert_exit_status() {

  lambda() {
    local val_fd=$(echo $@ | tr -d ' ' | cut -d':' -f2)
    local arg=$1
    shift
    shift
    local cmd=$(echo $@ | xargs -E ':')
    local val=$(cat $val_fd)
    eval $arg=$val
    eval $cmd
  }

  local lambda=$1
  shift

  eval $@
  local ret=$?
  $lambda : <(echo $ret)

}

उपयोग:

assert_exit_status 'lambda status -> [[ $status -ne 0 ]] && echo Status is $status.' lls

उत्पादन

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