टाइम कमांड के समान, कमांड से बाहर निकलें कोड को लॉग करें


10

का उपयोग करते हुए

time sleep 1

पैदावार:

$ time sleep 1

real    0m1.005s
user    0m0.001s
sys     0m0.001s

क्या कोई ऐसा आदेश है जिसका उपयोग मैं बाहर निकलने के कोड को प्रिंट करने के लिए कर सकता हूं sleepया मैं जो भी कमांड चलाना चाहता हूं?

कुछ पसंद:

$ log-exit-code sleep 1

शायद यह पर्याप्त है?

sleep 1 && echo "$?"

3
नहीं, sleep 1 && echo $?स्लीपर सेल का कोड तभी प्रिंट होगा जब यह शून्य हो ...
Satats Katsura


1
sleep 1 && echo "$?" || echo "$?"
jesse_b

2
मैंने एक उत्तर के रूप में अन्य सभी को जोड़ा, जो अब तक मूल वापसी मूल्य को छोड़ देते हैं, जो इमो खराब है (उन उत्तरों के बाद, $? हमेशा 0 है क्योंकि वे जो आखिरी काम करते हैं वह एक नापसंद है, जो हमेशा काम करता है। वे सभी रखना भूल गए। मूल वापसी मान, और इसे प्रदर्शित करने के बाद इसे वापस लौटाएं। इसलिए वे इसे केवल एक पर्यवेक्षक को दिखाते हैं, लेकिन बाकी स्क्रिप्ट के लिए इसे 'छिपाएँ', जो अब "$?" का उपयोग नहीं कर सकता है यह देखने के लिए कि क्या यह महत्वपूर्ण कमांड है? 0 या कुछ और ...)
ओलिवियर दुलाक

1
साथ ही नीचे दिए गए सभी समाधान इस कार्यक्षमता को आसानी से लागू कर सकते हैं। कुसलानंद का उदाहरण सिर्फ यह होगा:EXIT_CODE=$(tellexit command)
jesse_b

जवाबों:


4

मेरे परीक्षण में अब तक यह काम किया है:

command && echo "$?" || echo "$?"

यदि यह सफल होता है या यदि यह विफल रहता है, तो इसे निकास कोड को प्रतिध्वनित करना बताता है।

जैसा कि सातो ने बताया कि यह अनिवार्य रूप से समान है:

command; echo "$?"

एक चीज जो और / या कमांड को सार्थक बना सकती है वह कुछ इस तरह है:

command && echo "Success! Exit Code: $?" || echo "Failure! Exit Code: $?"

यदि आपको बाहर निकलने के कोड पर अभिनय करने के लिए अपनी स्क्रिप्ट की आवश्यकता है जैसा कि ओलिवियर की चिंता है, तो यह एक गैर मुद्दा है। आपकी स्क्रिप्ट कुछ इस तरह दिख सकती है:

command
case "$?" in; 
    0) echo "Command exited with: 0"
       <command if good>
       ;;
    1) echo "Command exited with: 1"
        <command if bad>
        ;;
    255) echo "Command exited with: 255"  # for ssh maybe?
         <command if 255>
         ;;
    *) echo "Command exited with: >2"
        <command for other exit code>
        ;;
esac

13
अरे, यह कैसे सिर्फ से बेहतर है command; echo $??
सातु कटसरा

4
मुझे लगता है कि यह नहीं है। command; echo $?बेहतर जवाब है।
jesse_b

उह यह लगता है कि यह सबसे अच्छा विकल्प है, इसलिए मैंने इसे उत्तर के रूप में चुना, अगर कोई असहमत हो, तो lmk
अलेक्जेंडर मिल्स

@AlexanderMills सिर्फ आप जानता है जो आपके सवाल का :-) सबसे उपयुक्त जवाब है
Kusalananda

1
मुझे यह नापसंद है: इसके बाद एक्ज़िट कोड बदल जाता है command ; echo $?क्योंकि echo $?हमेशा सफल होता है और इसलिए इसके बाद, $ का नया मूल्य? is 0. अब मूल रिटर्न कोड को प्रदर्शित करने के बाद भी रखने का एक तरीका है, अगर यह मूल रिटर्न कोड बाद में उपयोगी है (उदाहरण के लिए: स्क्रिप्ट में, रिटर्न कोड की जांच करना जारी रखने से पहले महत्वपूर्ण है)। कई समाधानों में से एक के लिए मेरा जवाब देखें (अधिकांश उत्तर यहां उसी तरह से बदले जा सकते हैं)
ओलिवियर दुलैक

11

cmd && echo "$?"यह तब तक काम नहीं करेगा, जब यह केवल जीरो प्रिंट echoकरेगा ( केवल पूर्ववर्ती कमांड के सफल समापन पर निष्पादित होगा)।

यहां आपके लिए एक छोटा शेल फ़ंक्शन दिया गया है:

tellexit () {
    "$@"

    local err="$?"
    printf 'exit code\t%d\n' "$err" >/dev/tty
    return "$err"
}

यह दिए गए कमांड के एक्जिट कोड को उसी तरह प्रिंट timeकरता है जैसे कमांड करता है।

$ tellexit echo "hello world"
hello world
exit code       0

$ tellexit false
exit code       1

पुनः निर्देशित करके printfकरने के लिए /dev/ttyसमारोह में, हम अभी भी उपयोग कर सकते हैं tellexitहमारे मानक उत्पादन या त्रुटि धाराओं में कबाड़ हो रही बिना पुनर्निर्देशन के साथ:

$ tellexit bash -c 'echo hello; echo world >&2' >out 2>err
exit code       0
$ cat out
hello
$ cat err
world

एक चर में निकास कोड को सहेजकर हम इसे कॉलर को वापस करने में सक्षम हैं:

$ tellexit false || echo 'failed'
exit code       1
failed

उसी फ़ंक्शन का एक कट्टर संस्करण भी संकेत को प्रिंट करता है जो कमांड को मार देता है यदि निकास कोड 128 से अधिक है (जिसका अर्थ है कि यह सिग्नल के कारण समाप्त हो गया है):

tellexit () {
    "$@"

    local err="$?"

    if [ "$err" -gt 128 ]; then
        printf 'exit code\t%d (%s)\n' "$err" "$(kill -l "$err")" >/dev/tty
    else
        printf 'exit code\t%d\n' "$err" >/dev/tty
    fi

    return "$err"
}

परिक्षण:

$ tellexit sh -c 'kill $$'
exit code       143 (TERM)

$ tellexit sh -c 'kill -9 $$'
Killed
exit code       137 (KILL)

( localबात की आवश्यकता है ash/ pdksh/ bash/ zsh, या आप इसे बदल सकते हैं, typesetजिसे कुछ अन्य गोले भी समझ सकते हैं।)


कूल, आप टेललेक्स का उपयोग कैसे करेंगे, इसे एक्शन में दिखाएं pls
अलेक्जेंडर मिल्स

1
@AlexanderMills अपडेट देखें।
Kusalananda

2
इसे मूल वापसी मूल्य रखना चाहिए और इसे अंत में वापस करना चाहिए।
ओलिवियर दुलैक

@OlivierDulac वास्तव में अच्छा अवलोकन! मैं संशोधन करूंगा।
Kusalananda

7

शेल रैपर फंक्शन वाली चीज का इस्तेमाल करें। शायद एक अलग नाम के साथ।

$ exito() { "$@"; echo $?; }
$ exito true
0
$ exito false
1
$ exito echo "test test"      
test test
0
$ 

(यह निश्चित रूप से मानक आउटपुट को दूषित करेगा, इसलिए या तो tty@ कुसलानंद द्वारा दिखाए गए का उपयोग करें या इंटरैक्टिव संदर्भों के बाहर इसका उपयोग न करें।)

निर्बाध क्षेत्र में उतरते हुए, कुछ गोले एक पाइप लाइन में सभी कमांडों की स्थिति पर रिपोर्ट कर सकते हैं, न कि पिछले एक ही, जैसे कि जेएसएच में यदि आप चाहते हैं कि पूरी पाइपलाइन से रिपोर्ट की गई विफलताएं:

% TRAPZERR() { print >/dev/tty $pipestatus }
% perl -e 'exit 42' | perl -e 'exit 99'
42 99
% false | perl -e 'exit 42' | perl -e 'exit 99'
1 42 99
% perl -e 'exit 42' | perl -e 'exit 99' | true
% 

TRAPZERR अन्यथा कोई त्रुटि नहीं होने पर ("कोई खबर अच्छी खबर नहीं है" प्रिंसिपल) फायर नहीं करता है।


1
इसे मूल वापसी मूल्य रखना चाहिए और इसे अंत में वापस करना चाहिए। प्रदर्शित करना (प्रिंटफ, इको) एक साधारण चीज ('-' आदि के साथ शुरू नहीं होती है) हमेशा काम करती है, और "प्रदर्शन" $ के बाद? " अब मूल्य "0" है जैसा कि डिस्प्ले ने काम किया
ओलिवियर दुलाक

7

GNU के timeपास इसके लिए एक विकल्प है:

time -f %x sleep 1
0

बाहर निकलने के कोड 1 से गुजरता है , जब तक कि सिग्नल 2 से नहीं मारा जाता :

$ /usr/bin/time -f %x sleep 1; echo $?
0
0

$ /usr/bin/time -f %x sleep 2x; echo $?
sleep: invalid time interval ‘2x’
Try 'sleep --help' for more information.
1
1

$ /usr/bin/time -f %x sleep 60s; echo $? # Press ^C before a minute elapses
0
2

यदि आप सिग्नल को मारने की स्थिति को जानना / संभालना चाहते हैं, -vतो स्ट्रिंग के लिए स्ट्रडर को पास और grep करें Command terminated by signal


1 बाहर निकलने वाले कोड को देखने के लिए ओलिवियर दुलैक को धन्यवाद।
2 इसके अलावा, आपको मारने के संकेत एक्जिट कोड से गुजरने के लिए स्टीफन चेजलस का धन्यवाद।


1
Interresting। GNU केवल लेकिन इंटररस्टिंग, जैसा कि एक (संभवतः) बाकी कोड के लिए मूल रिटर्न कोड का पालन करेगा (यानी, यह इसे "0" के साथ प्रतिस्थापित नहीं करता जैसा कि अन्य उत्तर करते हैं)
ओलिवियर दुलैक

2
0यदि कमांड मारा जाता है तो यह वापस आ जाता है।
स्टीफन चेज़लस

2
@ बिशप, मैं मानता हूं कि उन मामलों में 0 आदर्श से कम है। लेकिन ध्यान दें कि, जब कोई कमांड सिग्नल से मारा जाता है तो रिपोर्ट करने के लिए कोई सामान्य समझौता नहीं होता है। 128 + सिग्नल संख्या वापस करना कुछ गोले द्वारा उपयोग किया जाता है। तुम भी जैसी चीजों को देखने 256+signumया 384+signumया यहाँ तक कि signum/256या signum/256+0.5अगर एक कोर जनरेट किया गया था (वास्तव में स्थिति के आधार पर लौटे waitpid()256 से विभाजित)। कुछ एक पाठीय प्रतिनिधित्व (जैसे sigintया sigquit+core) देंगे । अभी भी शायद gnu.coreutils.bugs न्यूज़ग्रुप मैं सहमत पर चर्चा करने के लायक है।
स्टीफन चेज़लस

3
(वास्तव timeमें इसका हिस्सा नहीं है coreutils, यह अपनी बग मेलिंग सूची (Bug-time@gnu.org) के साथ अपने दम पर एक पैकेज है
Stéphane Chazelas

1
@bishop, system()ब्रायन कार्निघन ( kइन awk) या nawkसोलारिस के द्वारा बनाए गए फ्रीक्सडी की तुलना में अभी भी बनाए गए पारंपरिक शेक्स की तरह awkहै। awk 'BEGIN{print system("kill -s ABRT $$")}'आउटपुट 0.523438जब कोर डंप आकार सीमित नहीं है। के व्यवहार gawkके साथ व्यवहार में परिवर्तन के साथ हाल ही में बदल गया है, --traditionalया --posix(भी की वापसी मूल्य देख close(cmd)अधिक भिन्नता के लिए)
स्टीफन Chazelas

2

मैं अन्य सभी उत्तरों को नापसंद करता हूं (यद्यपि मैं उनकी चतुराई के लिए बहुत पसंद करता हूं): वे बाहर निकलने का कोड प्रदर्शित करते हैं लेकिन वे इसे भी चेज करते हैं। (प्रदर्शित हिस्सा सच है, इसलिए इसके बाद रिटर्न कोड 0 है)

यहाँ एक संशोधित संस्करण है:

do_and_tell () {
   "$@"
   returncode="$?"
   printf "Execution of : \n%s\n yelded a return code of: \n%s\n" "$*" "$returncode"
   return $returncode  # the interresting addition... keeps the commands return value.
}

## usage:

prompt$ do_and_tell true
Execution of : 
true
 yelded a return code of: 
0

prompt$ echo $?
0

prompt$ do_and_tell false
Execution of : 
false
 yelded a return code of: 
1

prompt$ echo $?
1

वास्तव में, @bishop उत्तर केवल दूसरा है जो इस मान को रखता है, लेकिन GNU के संस्करण पर निर्भर करता है, timeजो हमेशा उपलब्ध नहीं होता है।
ओलिवियर दुलक

2

थोड़ा और मजबूत होने के लिए, बाहर निकलने की स्थिति को एक अलग FD में भेजें ताकि इसे स्वतंत्र रूप से stdout / stderr पर संभाला जा सके:

exit_status() {
    "$@"
    rv=$?
    echo >&3 "$rv"
    return "$rv"
}

# exit status and stdout to stdout:
> exit_status echo "hello" 3>&1
hello
0

# exit_status to stdout, stdout to /dev/null
> exit_status echo "hello" 3>&1 1>/dev/null
0
> exit_status ehco "hello" 3>&1 1>/dev/null
ehco: command not found
127

# exit_status to stdout, stdout and stderr to /dev/null
> exit_status ehco "hello" 3>&1 &>/dev/null
127

नोट आपको FD3 के साथ कुछ करने की आवश्यकता होगी या यह कहेगा Bad file descriptor

इसे दूसरे प्रोग्राम के इनपुट से इन आउटपुट को प्रदान करने के लिए आगे कॉन्फ़िगर किया जा सकता है, दूसरे प्रोग्राम को एक से अधिक एफडी पर सुनकर; आप इसे 90 के शुरुआती किबाना की तरह इस्तेमाल कर सकते हैं :)


इसे मूल वापसी मूल्य रखना चाहिए और इसे अंत में वापस करना चाहिए। प्रदर्शित करना (प्रिंटफ, इको) एक साधारण चीज ('-' आदि के साथ शुरू नहीं होती है) हमेशा काम करती है, और "प्रदर्शन" $ के बाद? " अब मूल्य "0" है जैसा कि डिस्प्ले ने काम किया
ओलिवियर दुलाक

1

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

यदि यह एक समारोह में है:

function some-function () {
    local rc ## to avoid side effects
    ...
    some-command ## run any command
    rc=$?  ## save the return status in a variable
    echo "some-command returned $rc" ## optionally tell the user about it
    ...
    return $rc  ## at the end, if appropriate
}

यदि यह सीधे एक स्क्रिप्ट में है:

some-command ## run any command
rc=$?  ## save the return status in a variable
echo "some-command returned $rc" ## optionally tell the user about it
...
exit $rc    ## at the end to tell any calling script about it, if appropriate

(डक और कवर क्योंकि यह सटीक प्रश्न का उत्तर नहीं देता है ।)

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