यह
ओपन ग्रुप बेस स्पेसिफिकेशंस के सेक्शन 2.9.1 सिंपल कमांड्स में से (POSIX के लिए) प्रलेखित है । वहाँ पाठ की एक दीवार है; मैं अंतिम पैराग्राफ पर आपका ध्यान निर्देशित करता हूं:
यदि कमांड नाम है, तो कमांड सर्च एंड एक्ज़ेक्यूशन में वर्णित अनुसार निष्पादन जारी रहेगा । यदि कोई कमांड नाम नहीं है, लेकिन कमांड में कमांड प्रतिस्थापन है, कमांड अंतिम कमांड प्रतिस्थापन के निकास की स्थिति के साथ पूरा होगा। अन्यथा, कमांड शून्य निकास स्थिति के साथ पूरा होगा।
इसलिए, उदाहरण के लिए,
Command Exit Status
$ FOO=BAR 0 (but see also the note from icarus, below)
$ FOO=$(bar) Exit status from "bar"
$ FOO=$(bar) baz Exit status from "baz"
$ foo $(bar) Exit status from "foo"
यह कैसे काम करता है, भी है। लेकिन अंत में “इतना सरल नहीं” खंड भी देखें।
phk , उनके प्रश्न में असाइनमेंट एक कमांड स्थिति से बाहर निकलने की स्थिति की तरह है, जब कमांड प्रतिस्थापन है? , सुझाव देता है
... ऐसा प्रतीत होता है जैसे कि एक असाइनमेंट स्वयं एक कमांड के रूप में गिना जाता है ... एक शून्य निकास मान के साथ, लेकिन जो असाइनमेंट के दाईं ओर से पहले लागू होता है (जैसे, कमांड प्रतिस्थापन कॉल ...)
यह देखने का एक भयानक तरीका नहीं है। एक साधारण आदेश की वापसी स्थिति का निर्धारण करने के लिए एक कच्चे योजना (एक युक्त नहीं ;
, &
, |
, &&
या ||
) है:
- अंत या एक कमांड शब्द (आमतौर पर एक प्रोग्राम का नाम) तक पहुंचने तक बाएं से दाएं लाइन को स्कैन करें।
- यदि आप एक चर असाइनमेंट देखते हैं, तो लाइन के लिए रिटर्न की स्थिति सिर्फ 0 हो सकती है।
- यदि आप एक कमांड प्रतिस्थापन देखते हैं - अर्थात,
$(…)
- उस कमांड से निकास की स्थिति लें।
- यदि आप एक वास्तविक कमांड (कमांड प्रतिस्थापन में नहीं) तक पहुंचते हैं, तो उस कमांड से निकास की स्थिति लें।
लाइन के लिए वापसी की स्थिति आपके पास अंतिम संख्या है।
कमांड के तर्क के रूप में कमांड प्रतिस्थापन , जैसे, foo $(bar)
गिनती नहीं; आपको बाहर निकलने की स्थिति मिलती है foo
। Php की संकेतन paraphrase करने के लिए , यहाँ व्यवहार है
temporary_variable = EXECUTE( "bar" )
overall_exit_status = EXECUTE( "foo", temporary_variable )
लेकिन यह एक मामूली ओवरसिलेशन है। से समग्र वापसी की स्थिति
A = $ ( cmd 1 ) B = $ ( cmd 2 ) C = $ ( cmd 3 ) D = $ ( cmd 4 ) E = mc 2
से बाहर निकलने की स्थिति है । काम के बाद आती है काम 0 के लिए समग्र बाहर निकलें स्थिति निर्धारित नहीं करता है।
cmd4
E=
D=
icarus , phk के सवाल के अपने जवाब में , एक महत्वपूर्ण बिंदु उठाता है: चर को आसानी से सेट किया जा सकता है। पोसिक्स मानक के खंड 2.9.1 में तीसरा-से-अंतिम पैराग्राफ कहता है,
यदि कोई भी चर असाइनमेंट एक वैरिएबल के लिए एक मान निर्दिष्ट करने का प्रयास करता है जिसके लिए वर्तमान शेल वातावरण में रीडऑनली विशेषता सेट की जाती है (चाहे उस वातावरण में असाइनमेंट बनाया गया हो), तो एक चर असाइनमेंट त्रुटि होगी। इन त्रुटियों के परिणामों के लिए शेल त्रुटियों के परिणाम देखें ।
अगर तुम कहो तो
readonly A
C=Garfield A=Felix T=Tigger
वापसी स्थिति 1. है यह नहीं बात करता है, तो तार Garfield
, Felix
और / या Tigger
आदेश प्रतिस्थापन (रों) के साथ प्रतिस्थापित कर रहे हैं - लेकिन नीचे नोट देखें।
2.8.1.1 शैल त्रुटियों के परिणाम में पाठ का एक और गुच्छा है, और एक तालिका है, और इसके साथ समाप्त होती है
तालिका में दिखाए गए सभी मामलों में जहां एक इंटरैक्टिव शेल को बाहर निकलने की आवश्यकता नहीं है, शेल उस कमांड का कोई और प्रसंस्करण नहीं करेगा जिसमें त्रुटि हुई थी।
कुछ विवरण समझ में आते हैं; कुछ नहीं:
A=
काम कभी कभी रोकता के रूप में है कि अंतिम वाक्य निर्दिष्ट करने के लिए लगता है, कमांड लाइन। उपरोक्त उदाहरण में, के C
लिए सेट है Garfield
, लेकिन T
सेट नहीं है (और, ज़ाहिर है, न तो है A
)।
- इसी तरह,
निष्पादित करता है ,
लेकिन नहीं । लेकिन, मेरे बैश के संस्करणों में (जिसमें 4.1.X और 4.3.X शामिल हैं), यह निष्पादित करता है । (संयोग से, यह phk की व्याख्या को आगे बढ़ाता है कि असाइनमेंट का निकास मान असाइनमेंट के दाईं ओर से पहले लागू होता है।)
C=$(cmd1) A=$(cmd2) T=$(cmd3)
cmd1
cmd3
cmd2
लेकिन यहाँ एक आश्चर्य है:
बाश के मेरे संस्करणों में,
आसानी से ए
सी = कुछ ए = कुछ टी = कुछ सीएमडी 0
निष्पादित करता है । विशेष रूप से,cmd0
C = $ ( cmd 1 ) A = $ ( cmd 2 ) T = $ ( cmd 3 ) cmd 0
निष्पादित
और , लेकिन नहीं । (ध्यान दें कि यह उसके व्यवहार के विपरीत है जब कोई आदेश नहीं है।) और यह पर्यावरण में (साथ ही साथ ) सेट करता है । मुझे आश्चर्य है कि क्या यह बग में एक बग है।
cmd1
cmd3
cmd2
T
C
cmd0
इतना आसान नहीं:
इस उत्तर का पहला पैराग्राफ "साधारण कमांड" को संदर्भित करता है।
विनिर्देश कहता है,
एक "सरल कमांड" वैकल्पिक चर असाइनमेंट और पुनर्निर्देशन का एक क्रम है, किसी भी क्रम में, वैकल्पिक रूप से शब्दों और पुनर्निर्देशन के बाद, एक नियंत्रण ऑपरेटर द्वारा समाप्त किया जाता है।
ये मेरे पहले उदाहरण ब्लॉक में दिए गए कथन हैं:
$ FOO=BAR
$ FOO=$(bar)
$ FOO=$(bar) baz
$ foo $(bar)
जिनमें से पहले तीन में परिवर्तनशील कार्य शामिल हैं, और अंतिम तीन में कमांड प्रतिस्थापन शामिल हैं।
लेकिन कुछ परिवर्तनशील कार्य बहुत सरल नहीं हैं।
बैश (1) कहता है,
असाइनमेंट बयान भी करने के लिए तर्क के रूप में दिखाई दे सकते हैं alias
, declare
, typeset
, export
, readonly
, और local
अंतर्निहित आदेश ( घोषणा आदेशों)।
के लिए export
, POSIX विनिर्देश कहता है,
बाहर निकलें स्थिति
0सभी नाम ऑपरेंड सफलतापूर्वक निर्यात किए गए थे।
> 0कम से कम एक नाम निर्यात नहीं किया जा सकता है, या -p
विकल्प निर्दिष्ट किया गया था और एक त्रुटि हुई।
और POSIX समर्थन नहीं करता है local
, लेकिन बैश (1) कहता है,
यह local
एक समारोह के भीतर नहीं जब उपयोग करने के लिए एक त्रुटि है । वापसी की स्थिति 0 है जब तक local
किसी फ़ंक्शन के बाहर उपयोग नहीं किया जाता है, एक अमान्य नाम की आपूर्ति की जाती है, या नाम एक पठनीय चर है।
लाइनों के बीच में पढ़ते हुए, हम उस घोषणा आदेश को देख सकते हैं जैसे
export FOO=$(bar)
तथा
local FOO=$(bar)
अधिक पसंद हैं
foo $(bar)
जहां तक वे से बाहर निकलने स्थिति पर ध्यान न दें bar
और आप मुख्य कमान के आधार पर एक निकास दर्जा देने ( export
, local
, या foo
)। तो हमारे पास अजीब तरह का है
Command Exit Status
$ FOO=$(bar) Exit status from "bar"
(unless FOO is readonly)
$ export FOO=$(bar) 0 (unless FOO is readonly,
or other error from “export”)
$ local FOO=$(bar) 0 (unless FOO is readonly,
statement is not in a function,
or other error from “local”)
जिसे हम प्रदर्शित कर सकते हैं
$ export FRIDAY=$(date -d tomorrow)
$ echo "FRIDAY = $FRIDAY, status = $?"
FRIDAY = Fri, May 04, 2018 8:58:30 PM, status = 0
$ export SATURDAY=$(date -d "day after tomorrow")
date: invalid date ‘day after tomorrow’
$ echo "SATURDAY = $SATURDAY, status = $?"
SATURDAY = , status = 0
तथा
myfunc() {
local x=$(echo "Foo"; true); echo "x = $x -> $?"
local y=$(echo "Bar"; false); echo "y = $y -> $?"
echo -n "BUT! "
local z; z=$(echo "Baz"; false); echo "z = $z -> $?"
}
$ myfunc
x = Foo -> 0
y = Bar -> 0
BUT! z = Baz -> 1
सौभाग्य से शेलचेक त्रुटि पकड़ता है और SC2155 उठाता है , जो सलाह देता है
export foo="$(mycmd)"
को बदलना चाहिए
foo=$(mycmd)
export foo
तथा
local foo="$(mycmd)"
को बदलना चाहिए
local foo
foo=$(mycmd)
local
संबंध हैं? जैसेlocal foo=$(bar)
?