शेल लोकल वैरिएबल पर एग्जिट कोड असाइन करना


42
#!/bin/bash
function0()
{
 local t1=$(exit 1)
 echo $t1
}

function0

echoखाली मूल्य छापता है। मैंने उम्मीद की:

1

t1वेरिएबल को एग्जिट कमांड का रिटर्न वैल्यू क्यों नहीं दिया जाता है - 1?

जवाबों:


58

local t1=$(exit 1) शेल को बताता है:

  • exit 1एक उपधारा में चला ;
  • अपने आउटपुट को स्टोर करें (जैसा कि, यह पाठ मानक आउटपुट के लिए) एक चर में t1, फ़ंक्शन के लिए स्थानीय।

यह इस प्रकार सामान्य है कि t1समाप्त होने से खाली है।

( कमांड प्रतिस्थापन के$() रूप में जाना जाता है ।)

निकास कोड हमेशा सौंपा गया है $?, इसलिए आप कर सकते हैं

function0()
{
  (exit 1)
  echo "$?"
}

वह प्रभाव प्राप्त करने के लिए जिसे आप खोज रहे हैं। आप निश्चित रूप $?से दूसरे चर को असाइन कर सकते हैं :

function0()
{
  (exit 1)
  local t1=$?
  echo "$t1"
}

1
तुम्हें पता है, तुम हमेशा पाइप में भी वापसी डाल सकते हो। `$ (जाल 'प्रिंटफ़" :: एर्रानो: $? "0; # अब जो भी करें लेकिन - यह सुनिश्चित करेगा कि लिखा हुआ तार अंतिम प्रतिस्थापन पूरे संदर्भ संदर्भ के लिए अंतिम रिटर्न होगा।
mikeserv

1
@mikeserv क्या आपने एक बैकटिक याद किया? $(trap 'printf "::ERRNO:$?"' 0; # now do whatever however
Doktor J

12

बाहर निकलें कोड $ में संग्रहीत किया गया था ? चर। कमांड प्रतिस्थापन का उपयोग करके केवल आउटपुट कैप्चर करें, आपको सबस्क्राइब बनाने के लिए (...) का उपयोग करना चाहिए :

#!/bin/bash

func() {
  (exit 1)
  local t1=$?
  printf '%d\n' "$t1"
}

func

असाइनमेंट t1=$?का बिंदु इसका उपयोग करना है, नहीं? और $?असाइनमेंट सेशन से क्लोब नहीं मिलेगा? मुझे लगता है मैं पूछ रहा हूँ कि यह नहीं होना चाहिएprintf '%d\n' "${t1}"
Dani_l

@ दान_ल: धन्यवाद, यह गलत टाइपो है। अपडेट किया गया।
congonglm

ध्यान दें कि कमांड प्रतिस्थापन केवल तब तक मानक को पकड़ लेता है जब तक कि अलग-अलग पुनर्निर्देशित नहीं किया जाता है।
फ्यट

7

में bashइस काम करता है:

loc(){  local   "x=$(exit "$1"):$?"
        printf  '$%s:\t%d\n' \
                 x "${x##*:}" \? "$?"
}

यह आदेश मूल्यांकन और चर असाइनमेंट के आदेश के साथ करना है। localएक वापसी मूल्य अपने सभी - और यह वर्तमान में निष्पादित कमांड है, न कि कमांड प्रतिस्थापन। कारण जैसी बातें ...

x=$(exit 1); echo "$?"

... 1 वापस आ सकता है क्योंकि उस कमांड में कभी भी कोई रिटर्न नहीं होता है सिवाय इसके कि सबस्क्रिप्शन चलाने के लिए सब- $xवेल्यू असाइन की जाए - इसलिए $?क्लोबबर्ड नहीं मिलता है क्योंकि यह व्यावहारिक रूप से हर दूसरे मामले में होता है जिसमें कमांड सब्स्टीट्यूशन का उपयोग किया जाता है।

वैसे भी, के साथ localयह है clobbered कर - जब विस्तार अभी भी मूल्यांकन किया जा रहा है कर रहे हैं और जो - लेकिन आप सही समय पर इसे पकड़ अगर पहले local आप अभी भी इसे प्रदान कर सकते हैं - के दिनचर्या यह पीटना करने के लिए एक मौका है।

unset x; loc 130; echo "${x-\$x is unset}"

... प्रिंट ...

$x: 130
$?: 0
$x is unset

हालांकि आपको पता होना चाहिए कि कई गोले में आप $?उस तरह से मध्य-मूल्यांकन निर्धारित करने पर भरोसा नहीं कर सकते । वास्तव में, ऐसा शायद इसलिए है क्योंकि वे गोले हर संभव समय पर पुनर्मूल्यांकन करने की जहमत नहीं उठाते हैं जैसा कि शायद bash- जो मैं तर्क करता हूं वह शायद बेहतर व्यवहार है bash। क्या आप वास्तव में अपने दुभाषिया पुनरावर्ती लूप-मूल्यांकन मूल्यों को चाहते हैं जो आपके द्वारा उपयोग करने का मौका होने से पहले बहुत हद तक अधिलेखित होने की संभावना है?

वैसे भी, आप ऐसा कर सकते हैं।


-1

इस बात पर निर्भर करता है कि आप केवल बाहर निकलने का कोड प्राप्त करने का प्रयास क्यों कर रहे हैं, आप बस चला सकते हैं if some-command; then echo "Success $?"; else echo "Failure $?"; fiजो कमांड के आउटपुट के साथ कुछ भी नहीं करता है, यह सिर्फ कमांड रन के निकास कोड का मूल्यांकन करता है। आप जोड़ सकते हैं or( or$ ( around the command and you'll still get the same results. A better example might beअगर grep -q 'somestring' somefile; तो गूंज "सोमेस्ट्रिंग एग्जिट कोड $ है?);" "सोमेस्ट्रिंग एग्जिट कोड नहीं मिला?"; फाई `।

आप किसी फ़ंक्शन के रिटर्न कोड का भी परीक्षण कर सकते हैं जो या तो एक स्पष्ट return 3या एक निहित रिटर्न कोड हो सकता है, जो अंतिम कमांड का परिणाम है, इस मामले में आपको सावधान रहने की आवश्यकता है कि आपके पास echoअंत में नहीं है फ़ंक्शन, अन्यथा यह पिछले निकास कोड को मास्क / रीसेट करता है।

command_last () {
  echo "True is `true`"
  echo "False is `false`"
  false
}
command_last; echo $?
# Outputs:
# True is 0
# False is 1
# 1

echo_last () {
  echo "True is `true`"
  echo "False is `false`"
  false
  # echo'ing literally anything (or nothing) returns true aka exit 0
  echo
}
echo_last; echo $?
# Outputs:
# True is 0
# False is 1
#            # Blank line due to empty echo
# 0

अंत में एक गंदा चाल क्योंकि आप नहीं कर सकते VAR=(SOME_COMMAND)क्योंकि VAR=()एक सरणी परिभाषा है, इसलिए आपको इसकी आवश्यकता है VAR=( $(echo 'Some value') )


सभी दावा किए गए आउटपुट गलत हैं, इस तथ्य के कारण कि कमांड प्रतिस्थापन बाहर निकलने का कोड नहीं देता है, जो प्रश्न का पूरा बिंदु है। यह स्पष्ट नहीं है कि "गंदी चाल" का किसी भी चीज़ से क्या लेना-देना है।
निक मैटेओ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.