linux बैश में कमांड प्रतिस्थापन के लिए चर असाइनमेंट के बाहर निकलें कोड




bash shell (4)

ध्यान दें कि किसी फ़ंक्शन के भीतर local का उपयोग करते समय ऐसा नहीं होता है। जो कि स्वीकृत उत्तर और वर्णित पोस्ट की तुलना में सामान्य रूप से भिन्न व्यवहार है: BASHFAQ/002

उदाहरण के लिए इस बैश स्क्रिप्ट को लें:

#!/bin/bash
function funWithLocalVar() {
    local output="$(echo "Doing some stuff.";exit 1)"
    local exitCode=$?
    echo "output: $output"
    echo "exitCode: $exitCode"
}

function funWithoutLocalVar() {
    output="$(echo "Doing some stuff.";exit 1)"
    local exitCode=$?
    echo "output: $output"
    echo "exitCode: $exitCode"
}

funWithLocalVar
funWithoutLocalVar

यहाँ इस का उत्पादन है:

nick.[email protected]-laptop1:~$ ./tmp.sh 
output: Doing some stuff.
exitCode: 0
output: Doing some stuff.
exitCode: 1

शायद किसी को परवाह नहीं है, लेकिन मैंने किया। मुझे यह पता लगाने में एक मिनट लगा कि मेरा स्टेटस कोड हमेशा 0 क्यों था जब यह स्पष्ट रूप से कभी-कभी नहीं था। 100% स्पष्ट क्यों नहीं। लेकिन सिर्फ यह जानने से मदद मिली।

मैं इस बात को लेकर असमंजस में हूँ कि एक चर असाइनमेंट को सादे तरीके से और कमांड प्रतिस्थापन के साथ निष्पादित करने पर कमांड किस त्रुटि कोड को लौटाएगी:

a=$(false); echo $?

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

false; a=""; echo $?

यह 0 आउटपुट करता है, जाहिर है कि यह a="" रिटर्न है और यह 1 false द्वारा वापस आ गया false

मैं जानना चाहता हूं कि ऐसा क्यों होता है, क्या चर असाइनमेंट में कोई खासियत है जो अन्य सामान्य कमांड से अलग है? या सिर्फ a=$(false) कारण हो सकता a=$(false) को एक ही आदेश माना जाता है और केवल कमांड प्रतिस्थापन भाग समझ में आता है?

-- अद्यतन करें --

सभी को धन्यवाद, उत्तर और टिप्पणियों से मुझे यह बात मिली "जब आप कमांड प्रतिस्थापन का उपयोग करके एक चर असाइन करते हैं, तो निकास स्थिति कमांड की स्थिति है।" (@Barmar द्वारा), यह स्पष्टीकरण स्पष्ट रूप से स्पष्ट और समझने में आसान है, लेकिन प्रोग्रामर के लिए पर्याप्त सटीक नहीं बोलता है, मैं इस बिंदु के संदर्भ को TLDP या GNU मैन पेज जैसे अधिकारियों से देखना चाहता हूं, कृपया मुझे इसे खोजने में मदद करें बाहर, धन्यवाद फिर से!


(मूल प्रश्न का उत्तर नहीं बल्कि टिप्पणी के लिए बहुत लंबा है)

ध्यान दें कि export A=$(false); echo $? export A=$(false); echo $? आउटपुट 0! जाहिर तौर पर देवनुल के जवाब में उद्धृत नियम अब लागू नहीं होते हैं। उस उद्धरण (संदर्भ मेरा) के संदर्भ में थोड़ा सा जोड़ने के लिए:

3.7.1 सरल कमांड विस्तार

...

यदि विस्तार के बाद कोई कमांड नाम बचा है, तो निष्पादन कार्यवाही नीचे बताई गई हैअन्यथा , कमांड से बाहर निकलता है। यदि किसी एक विस्तार में कमांड प्रतिस्थापन होता है, तो कमांड की निकास स्थिति अंतिम कमांड प्रतिस्थापन की निकास स्थिति होती है। यदि कोई कमांड प्रतिस्थापन नहीं थे, तो कमांड शून्य की स्थिति के साथ बाहर निकलता है।

3.7.2 कमांड खोज और निष्पादन [- यह "नीचे" मामला है ]

IIUC मैनुअल var=foo को var=foo command... विशेष मामले के रूप में वर्णित करता है var=foo command... वाक्यविन्यास (बहुत भ्रमित!)। "अंतिम कमांड प्रतिस्थापन की स्थिति" नियम केवल नो-कमांड मामले पर लागू होता है।

हालांकि यह export var=foo को "संशोधित असाइनमेंट सिंटैक्स" के रूप में सोचने के लिए लुभा रहा है, यह नहीं है - export एक अंतर्निहित कमांड है (जो कि असाइनमेंट-जैसे आर्ग्स लेने के लिए होता है)।

=> यदि आप एक var निर्यात करना चाहते हैं और कमांड प्रतिस्थापन स्थिति पर कब्जा करना चाहते हैं, तो इसे 2 चरणों में करें:

A=$(false)
# ... check $?
export A

यह तरीका set -e मोड में भी काम करता है - यदि कमांड प्रतिस्थापन नॉन -० पर लौटाता है तो तुरंत बाहर निकल जाता है।


मैं कल (अगस्त 29 2018) उसी समस्या को लेकर आया था।

निक पी। के उत्तर में local उल्लिखित उत्तर में @ सेवको की टिप्पणी के अलावा, वैश्विक दायरे में declare किया गया व्यवहार भी समान है।

यहाँ मेरा बैश कोड है:

#!/bin/bash

func1()
{
    ls file_not_existed
    local local_ret1=$?
    echo "local_ret1=$local_ret1"

    local local_var2=$(ls file_not_existed)
    local local_ret2=$?
    echo "local_ret2=$local_ret2"

    local local_var3
    local_var3=$(ls file_not_existed)
    local local_ret3=$?
    echo "local_ret3=$local_ret3"
}

func1

ls file_not_existed
global_ret1=$?
echo "global_ret1=$global_ret1"

declare global_var2=$(ls file_not_existed)
global_ret2=$?
echo "global_ret2=$global_ret2"

declare global_var3
global_var3=$(ls file_not_existed)
global_ret3=$?
echo "global_ret3=$global_ret3"

उत्पादन:

$ ./declare_local_command_substitution.sh 2>/dev/null 
local_ret1=2
local_ret2=0
local_ret3=2
global_ret1=2
global_ret2=0
global_ret3=2

उपरोक्त आउटपुट में local_ret2 और global_ret2 के मूल्यों पर ध्यान दें। निकास कोड local और declare द्वारा ओवरराइट किए गए हैं।

मेरा बैश संस्करण:

$ echo $BASH_VERSION 
4.4.19(1)-release

$(command) रूप में एक कमांड निष्पादित करने पर कमांड के आउटपुट को स्वयं को बदलने की अनुमति देता है

जब आप कहें:

a=$(false)             # false fails; the output of false is stored in the variable a

कमांड false द्वारा उत्पादित आउटपुट को चर में संग्रहीत किया जाता a । इसके अलावा, निकास कोड कमांड द्वारा उत्पादित के समान है। help false करेगा बताओ:

false: false
    Return an unsuccessful result.

    Exit Status:
    Always fails.

दूसरी ओर, यह कहते हुए:

$ false                # Exit code: 1
$ a=""                 # Exit code: 0
$ echo $?              # Prints 0

असाइनमेंट के एग्जिट कोड को वापस करने का कारण बनता है जो कि 0

संपादित करें:

manual से उद्धरण:

यदि किसी एक विस्तार में कमांड प्रतिस्थापन होता है, तो कमांड की निकास स्थिति अंतिम कमांड प्रतिस्थापन की निकास स्थिति होती है।

BASHFAQ/002 से BASHFAQ/002 :

मैं एक चर में एक कमांड के रिटर्न मान और / या आउटपुट को कैसे स्टोर कर सकता हूं?

...

output=$(command)

status=$?

output असाइनमेंट का command की निकास स्थिति पर कोई प्रभाव नहीं पड़ता है, जो अभी भी $?





exit-code