क्या चर $ 0 और $ 1 शेल / पर्यावरण चर जैसे हैं?


17

वहाँ कवच की तरह में चर रहे हैं $0, $1, $2, $?, आदि

मैंने निम्नलिखित कमांड का उपयोग करके शेल और पर्यावरण चर को प्रिंट करने की कोशिश की:

set

लेकिन ये चर सूची में नहीं थे।

तो मूल रूप से इन चर को शेल / पर्यावरण चर नहीं माना जाता है, है ना? (भले ही उन्हें आउटपुट करने के लिए, आपको उनके साथ पूर्ववर्ती होना होगा $, जैसे आप शेल / पर्यावरण चर के साथ करते हैं)


3
स्थितीय पैरामीटर चर नहीं हैं। आप एक पर्यावरण चर में export 3बदल नहीं सकते $3। तुम नहीं कर सकते unset 3; और आप $3एक नए मान का उपयोग नहीं कर सकते 3=val
कज़

जवाबों:


25

चर शैल में तीन अलग-अलग किस्मों के मापदंडों में से एक हैं।

  1. एक चर एक पैरामीटर है जिसका नाम एक मान्य शेल पहचानकर्ता है; _एक अक्षर से शुरू होता है, उसके बाद शून्य या उससे अधिक अक्षर, संख्या या _
  2. स्थितीय मापदंडों गिने मापदंड हैं $1, $2...
  3. विशेष मापदंडों सभी एकल-चरित्र के नाम है, और से अलग $0है, वे सभी विभिन्न विराम चिह्न वर्ण हैं।

set केवल शेल के चर प्रदर्शित करता है।

शेल चर का एक सबसेट पर्यावरण चर हैं, जिनके मूल्य शेल के शुरू होने पर या तो पर्यावरण से विरासत में प्राप्त होते हैं, या exportमान्य नाम पर विशेषता सेट करके बनाए जाते हैं ।


1
ध्यान दें कि setसभी मापदंडों को प्रदर्शित करता है zsh($ 1, $ 2 ... लेकिन $ *, $ @) और बाश और बोश में कार्य नहीं करता है। Ksh93 जैसे कुछ गोले और डैश आउटपुट एनवी वर्जन के पुराने संस्करण जिन्हें शेल वेरिएबल्स में मैप नहीं किया गया था। ( env 1=foo ksh -c setप्रिंट होगा 1=foo)
स्टीफन Chazelas

11

पर्यावरण चर बनाम स्थितिगत पैरामीटर

इससे पहले कि हम $INTEGERचर के प्रकार पर चर्चा करना शुरू करें , हमें यह समझने की आवश्यकता है कि वे वास्तव में क्या हैं और वे पर्यावरण चर से कैसे भिन्न होते हैं। चर जैसे $INTEGERस्थितिगत मापदंडों को कहा जाता है। यह POSIX (पोर्टेबल ऑपरेटिंग सिस्टम इंटरफ़ेस) मानक, खंड 2.1 (जोर मेरा) में वर्णित है :

  1. शेल एक फ़ंक्शन निष्पादित करता है (फ़ंक्शन परिभाषा कमांड देखें), बिल्ट-इन (विशेष निर्मित-उपयोगिताओं को देखें), निष्पादन योग्य फ़ाइल या स्क्रिप्ट, स्थिति के मापदंडों के रूप में तर्कों के नाम 1 से n तक गिने, और कमांड का नाम। (या स्क्रिप्ट के भीतर एक फ़ंक्शन के मामले में, स्थिति के पैरामीटर के रूप में स्क्रिप्ट का नाम) 0 गिना गया (कमांड खोज और निष्पादन देखें)।

इसके विपरीत, चर जैसे कि $HOMEऔर $PATHपर्यावरण चर हैं। उनकी परिभाषा मानक की धारा 8 में वर्णित है :

इस अध्याय में परिभाषित पर्यावरण चर कई उपयोगिताओं, कार्यों और अनुप्रयोगों के संचालन को प्रभावित करते हैं। अन्य पर्यावरण चर हैं जो केवल विशिष्ट उपयोगिताओं के लिए रुचि रखते हैं। पर्यावरण चर जो केवल एक उपयोगिता पर लागू होते हैं, उन्हें उपयोगिता विवरण के भाग के रूप में परिभाषित किया जाता है।

उनके विवरण पर ध्यान दें। स्थितिगत पैरामीटर एक कमांड के सामने प्रकट होने के लिए होते हैं, अर्थात command positional_arg_1 positional_arg_2...। वे उपयोगकर्ता द्वारा यह बताने के लिए प्रदान किए जाते हैं कि विशेष रूप से क्या करना है। जब आप ऐसा करते हैं echo 'Hello' 'World', तो यह Helloऔर Worldस्ट्रिंग्स को प्रिंट करेगा , क्योंकि ये स्थिति के पैरामीटर हैं echo- जिन चीजों को आप echoसंचालित करना चाहते हैं। और echoइस तरह बनाया गया है कि यह स्थितिजन्य मापदंडों को स्ट्रिंग्स के रूप में मुद्रित करने के लिए समझता है (जब तक कि वे वैकल्पिक झंडे में से एक न हों -n)। यदि आप अलग-अलग कमांड के साथ ऐसा करते हैं तो यह समझ में नहीं आता कि क्या Helloऔर क्याWorldक्योंकि शायद यह एक संख्या की उम्मीद है। ध्यान दें कि स्थितिगत पैरामीटर "विरासत में नहीं" हैं - एक बच्चे की प्रक्रिया को माता-पिता की स्थितिगत मापदंडों के बारे में नहीं पता है जब तक कि स्पष्ट रूप से बच्चे की प्रक्रिया के लिए पारित नहीं किया जाता है। अक्सर आप स्थितीय मापदंडों को रैपर स्क्रिप्ट्स के साथ पास करते हुए देखते हैं - जो कि पहले से ही कमांड के मौजूदा उदाहरण के लिए जाँच करते हैं या वास्तविक कमांड के लिए अतिरिक्त स्थितीय मापदंडों को जोड़ते हैं जिन्हें कहा जाएगा।

इसके विपरीत, पर्यावरण चर कई कार्यक्रमों को प्रभावित करने के लिए होते हैं। वे पर्यावरण चर रहे हैं , क्योंकि वे कार्यक्रम के बाहर ही सेट कर रहे हैं (नीचे इस पर और अधिक)। इस तरह के रूप में कुछ वातावरण चर HOMEया PATHविशिष्ट स्वरूप, विशेष अर्थ है, और वे प्रत्येक कार्यक्रम के लिए एक ही मतलब होगा। HOMEवैरिएबल का अर्थ बाहरी उपयोगिता जैसे /usr/bin/findया आपके शेल (और इसके परिणामस्वरूप स्क्रिप्ट) से होता है - यह उपयोगकर्ता नाम का होम डायरेक्टरी है जिसके तहत प्रक्रिया चलती है। उदाहरण के लिए, विशिष्ट चर व्यवहार के लिए पर्यावरण चर का उपयोग किया जा सकता हैUIDपर्यावरण चर का उपयोग यह जांचने के लिए किया जा सकता है कि स्क्रिप्ट रूट विशेषाधिकारों के साथ चलती है या नहीं और तदनुसार विशिष्ट कार्यों के लिए शाखा। पर्यावरण चर अंतर्निहित हैं - बच्चे की प्रक्रियाओं को माता-पिता के पर्यावरण की नकल मिलती है। यह भी देखें कि यदि प्रक्रियाएं माता-पिता के वातावरण को विरासत में देती हैं, तो हमें निर्यात की आवश्यकता क्यों है?

संक्षेप में, मुख्य अंतर यह है कि पर्यावरण चर को कमांड के बाहर सेट किया जाता है और इसका मतलब विविध (आमतौर पर) नहीं होता है, जबकि स्थितिगत पैरामीटर ऐसी चीजें हैं जो कमांड द्वारा संसाधित होने वाली होती हैं और वे बदल जाती हैं।


सिर्फ शेल कॉन्सेप्ट नहीं

मैंने टिप्पणियों से देखा है कि आप टर्मिनल और शेल को मिला रहे हैं, और वास्तव में आपको वास्तविक टर्मिनलों के बारे में पढ़ने की सलाह देंगे जो एक बार भौतिक उपकरण थे। आजकल, "टर्मिनल" जिसका हम आम तौर पर उल्लेख कर रहे हैं, काली पृष्ठभूमि और हरे रंग की पाठ वाली खिड़की वास्तव में सॉफ्टवेयर है, एक प्रक्रिया है। टर्मिनल एक प्रोग्राम है जो एक शेल चलाता है, जबकि शेल भी एक प्रोग्राम है, लेकिन एक वह है जो पढ़ता है कि आप क्या निष्पादित करने के लिए टाइप करते हैं (यानी, यदि यह इंटरैक्टिव शेल है, तो गैर-इंटरैक्टिव शेल स्क्रिप्ट और sh -c 'echo foo'इनवोकेशन के प्रकार हैं)। यहाँ गोले पर अधिक ।

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

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

int main(int argc, char **argv)

, जहां argcकमांड-लाइन तर्कों की संख्या है और argvप्रभावी रूप से कमांड-लाइन मापदंडों की सरणी है, और फिर उपयोगकर्ता के घर निर्देशिका पथ, निर्देशिकाओं की सूची, जहां हम निष्पादन योग्य की तलाश कर सकते हैं, आदि जैसी चीजों तक पहुंचने के लिए environफ़ंक्शन (लिनक्स पर man -e 7 environ) है PATH। शैल लिपियों को भी इसी तरह से तैयार किया गया है। शेल शब्दावली में, हमारे पास स्थितीय पैरामीटर हैं $1, $2और आगे, जबकि $#स्थितीय मापदंडों की संख्या है। किस बारे में $0? यह स्वयं निष्पादन योग्य का नाम है, जिसे फिर से सी प्रोग्रामिंग भाषा से भी तैयार किया गया है - argv[0]यह आपके सी "निष्पादन योग्य" का नाम होगा। और यह अधिकांश प्रोग्रामिंग और स्क्रिप्टिंग भाषाओं के लिए काफी हद तक सही है ।

इंटरएक्टिव बनाम गैर-इंटरैक्टिव गोले

एक चीज़ जो मैंने पहले ही बताई है, वह है इंटरएक्टिव और नॉन-इंटरेक्टिव गोले का अंतर । प्रॉम्प्ट जहाँ आप कमांड्स में टाइप करते हैं - यह इंटरैक्टिव है, यह उपयोगकर्ता के साथ इंटरैक्ट करता है। इसके विपरीत जब आपके पास एक शेल स्क्रिप्ट होती है या आप bash -c''गैर-संवादात्मक होते हैं।

और यहीं से भेद महत्वपूर्ण हो जाता है। वह शेल जो आप पहले से चला रहे हैं, एक प्रक्रिया है, जिसे स्थितीय मापदंडों के साथ देखा गया था ( bashलॉगिन शेल के लिए एक है "... जिसका तर्क शून्य का पहला वर्ण a है - या किसी ने - thelogin विकल्प से शुरू किया है।" ( संदर्भ ) )

इसके विपरीत, स्क्रिप्ट और -cविकल्प के साथ लॉन्च किए गए गोले $1और $2तर्कों का लाभ उठा सकते हैं । उदाहरण के लिए,

$ bash -c 'echo $1; stat $2' sh 'Hello World' /etc/passwd
Hello World
  File: '/etc/passwd'
  Size: 2913        Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 6035604     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2017-08-12 14:48:37.125879962 -0600
Modify: 2017-08-12 14:48:37.125879962 -0600
Change: 2017-08-12 14:48:37.137879811 -0600
 Birth: -

ध्यान दें कि मैंने shवहां भी उपयोग किया है, क्योंकि -cविकल्प का छोटा क्वर्की पहले स्थितीय पैरामीटर को लेना है और इसे असाइन करना है $0, आमतौर पर प्रोग्राम का नाम होने के विपरीत।

एक और बात जो नोटिस करना महत्वपूर्ण है, वह यह है कि स्थितिगत मापदंड वही हैं जिन्हें मैं "फ्रैमेबल" कहता हूं। ध्यान दें कि कैसे, हमने पहली बार bashअपने स्वयं के स्थितीय मापदंडों के साथ लॉन्च किया था , लेकिन वे स्थितियां मापदंडों के लिए echoऔर बन गईं stat। और प्रत्येक कार्यक्रम इसे अपने तरीके से समझता है। यदि हमने statएक स्ट्रिंग दी Hello Worldऔर कोई फाइल नहीं है तो Hello Worldयह एक त्रुटि उत्पन्न करेगा; bashइसे सिर्फ एक साधारण स्ट्रिंग के रूप में मानते हैं, लेकिन statउस स्ट्रिंग को एक मौजूदा फ़ाइल नाम होने की उम्मीद करते हैं। इसके विपरीत, सभी कार्यक्रम सहमत होंगे कि पर्यावरण चर HOMEएक निर्देशिका है (जब तक कि प्रोग्रामर ने इसे अनुचित तरीके से कोडित नहीं किया है)।


क्या हम पर्यावरण चर और स्थितिगत मापदंडों के साथ खिलवाड़ कर सकते हैं?

तकनीकी रूप से, हम दोनों के साथ गड़बड़ कर सकते हैं, लेकिन हमें पर्यावरण चर के साथ गड़बड़ नहीं करनी चाहिए , जबकि हमें अक्सर स्थितीय पैरामीटर प्रदान करना होता है। हम उदाहरण के लिए, एक चर को प्रस्तुत करने के साथ शेल में कमांड चला सकते हैं:

$ hello=world bash -c 'echo $hello'
world

हम केवल export variable=valueशेल या स्क्रिप्ट के भीतर से चर को पर्यावरण में रख सकते हैं । या हम पूरी तरह से खाली वातावरण के साथ एक कमांड चला सकते हैं env -c command arg1 arg2। हालांकि, आम तौर पर पर्यावरण के साथ खिलवाड़ करने की सिफारिश नहीं की जाती है, विशेष रूप से ऊपरी-केस चर या पहले से मौजूद पर्यावरण चर का ओवरराइटिंग। सूचना है कि एक मानक नहीं है, हालांकि सिफारिश की है।

स्थितीय मापदंडों के लिए, उन्हें सेट करने का तरीका स्पष्ट है, बस उन्हें कमांड में प्रस्तुत करना है, लेकिन उन्हें अन्य बुद्धिमानों को सेट करने के तरीके भी हैं , साथ ही shiftकमांड के माध्यम से उन मापदंडों की सूची को बदलना है ।

अंत में, इन दोनों का उद्देश्य अलग है, और वे एक कारण के लिए मौजूद हैं। मुझे आशा है कि लोगों ने इस उत्तर से कुछ अंतर्दृष्टि प्राप्त की, और इसे पढ़ने में मज़ा आया क्योंकि यह मेरे लिए यह उत्तर लिखना था।


सेट कमांड पर ध्यान दें

setआदेश है, इसलिए की तरह बर्ताव करता है मैनुअल के अनुसार (बैश पुस्तिका से, जोर जोड़ा):

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

दूसरे शब्दों में set, शेल के लिए विशिष्ट चर को देखते हैं, जिनमें से कुछ पर्यावरण में होते हैं, उदाहरण के लिए HOME। इसके विपरीत कमांड जैसी envऔर printenvवास्तविक पर्यावरण चर को देखो जिसके साथ एक कमांड चलता है। यह भी देखें इस


"इंटरेक्टिव शेल में, आप $ 1, $ 2 और बहुत आगे का संदर्भ नहीं दे सकते।" क्या इसके लिए कोई सीधा संदर्भ है? मैं अजीब मामलों में भाग गया हूं जहां ये एक इंटरैक्टिव शेल वातावरण में सेट किए गए हैं और मुझे यकीन नहीं है कि यह 'गैर-मानक' माना जाएगा या नहीं।
user5359531

@ user5359531 ईमानदारी से, मुझे बिल्कुल यकीन नहीं है कि मुझे वह कहाँ से मिला है। शायद इसलिए क्योंकि जब मैंने 2017 में जवाब पोस्ट किया था तो मैंने संभवतः यह उल्लेख किया था कि आप ऐसा कुछ नहीं कर सकते हैं, 1="foo"लेकिन बाद में मुझे पता चला कि पोसिक्स ने एक "शब्द" (जो कि किसी वस्तु का नाम है जैसे कि चर या फ़ंक्शन) शुरू नहीं कर सकता है। एक अंक के साथ (एक सवाल मैं इस विषय पर पोस्ट देखें )। स्थितिगत नियम स्पष्ट रूप से इस नियम के अपवाद हैं।
सर्गी कोलोडियाज़नी

@ user5359531 मैंने उत्तर का हिस्सा हटा दिया है, क्योंकि यह विशेष रूप से सटीक नहीं है। आप इंटरेक्टिव शेल में संदर्भ दे सकते हैं $1, $2और वास्तव में, यह setकमांड के साथ किया जाता है , अक्सर /bin/shएरे को न रखने की सीमा के आसपास पाने के लिए । इसे मेरे ध्यान में लाने के लिए धन्यवाद। मैं अगले कुछ दिनों में उत्तर को संपादित करने जा रहा हूं, क्योंकि इसमें थोड़ी अतिरिक्त पॉलिश और एक अद्यतन की आवश्यकता है।
सर्गी कोलोडियाज़नी

स्पष्टीकरण के लिए धन्यवाद। समस्या मैं कर रहा हूँ उस के साथ है conda, जब आप चलाने के source conda/bin/activateलिए, यह है कि क्या के लिए चेक $1, $2आदि, सेट कर रहे हैं, के क्रम में निर्धारित करने के लिए अगर यह तर्क या नहीं के साथ एक स्क्रिप्ट के रूप में चलाया गया था। यह उन प्रणालियों पर ब्रेकिंग को समाप्त करता है जिनके पास किसी कारण से इंटरैक्टिव वातावरण में सेट है। मैं यह पता लगाने की उम्मीद कर रहा हूं कि क्या यह गैर-मानक व्यवहार इंटरएक्टिव वातावरण में इन चर को स्थापित करने के लिए सिस्टम में एक दोष है, या प्रोग्राम के रूप में यह निर्धारित करने के लिए कि क्या यह एक स्क्रिप्ट के रूप में चलाया गया था।
user5359531

@ user5359531 मैं आपको सुझाव दूंगा कि आप condaडेवलपर्स को बग रिपोर्ट दर्ज करें या जो कोई भी इस तरह की स्क्रिप्ट का मूल लेखक है, क्योंकि ${N}मापदंडों के लिए जाँच निश्चित रूप से जाने का गलत तरीका है। यहाँ और यहाँ एक ही विषय पर प्रश्न हैं , और अधिक या कम पोर्टेबल तरीके से यह जांचना है कि ${0}क्या स्क्रिप्ट नाम के समान है, जबकि bashवास्तव में उस उद्देश्य के लिए पर्यावरण चर है
Sergiy Kolodyazhnyy

4

$1, $2, $3, ..., ${10}, ${11}चर स्थितीय मापदंडों कहा जाता है और पार्टी के मैनुअल खंड में शामिल किया जाता है3.4.1

३.४.१ पोजीशन पैरामीटर्स

एक स्थितीय पैरामीटर एक पैरामीटर है जिसे एक या अधिक अंकों से दर्शाया जाता है, एकल अंक 0. के अलावा अन्य स्थितीय पैरामीटर शेल के तर्कों से निर्दिष्ट किए जाते हैं जब इसे लागू किया जाता है, और सेट बिल्डिन कमांड का उपयोग करके पुन: असाइन किया जा सकता है। स्थितीय पैरामीटर N को $ {N} या $ N के रूप में संदर्भित किया जा सकता है जब N में एक अंक होता है। स्थिति संबंधी मापदंडों को असाइनमेंट स्टेटमेंट के साथ नहीं सौंपा जा सकता है। सेट और शिफ्ट बिल्डिंस का उपयोग उन्हें सेट और अनसेट करने के लिए किया जाता है (शेल बिल्ड कमांड्स देखें)। जब शेल फ़ंक्शन निष्पादित किया जाता है (शेल फ़ंक्शंस देखें), तो स्थिति संबंधी मापदंडों को अस्थायी रूप से बदल दिया जाता है।

जब एक से अधिक अंकों से युक्त एक स्थितिगत पैरामीटर का विस्तार किया जाता है, तो इसे ब्रेसिज़ में संलग्न किया जाना चाहिए।

जैसा कि $?और $0, इन विशेष मापदंडों को अगले भाग में शामिल किया गया है3.4.2

3.4.2 विशेष पैरामीटर

शेल कई मापदंडों को विशेष रूप से मानता है। इन मापदंडों को केवल संदर्भित किया जा सकता है; उन्हें असाइनमेंट की अनुमति नहीं है।

...

?

($?) सबसे हाल ही में निष्पादित अग्रभूमि पाइपलाइन की निकास स्थिति का विस्तार करता है।

0

($ 0) शेल या शेल स्क्रिप्ट के नाम का विस्तार करता है। यह शेल इनिशियलाइजेशन पर सेट है। यदि बैश को आदेशों की एक फ़ाइल के साथ लागू किया जाता है (शेल लिपियों को देखें), $ 0 उस फ़ाइल के नाम पर सेट है। यदि बैश को -c ऑप्शन के साथ शुरू किया जाता है (इनवॉइस बैश देखें), तो $ 0 को स्ट्रिंग को निष्पादित करने के बाद पहले तर्क पर सेट किया जाता है, यदि कोई मौजूद है। अन्यथा, यह बैश को लागू करने के लिए उपयोग किए जाने वाले फ़ाइलनाम पर सेट है, जैसा कि तर्क शून्य द्वारा दिया गया है।


4

$1, $2... स्थितिगत पैरामीटर हैं , वे चर नहीं हैं, अकेले पर्यावरण चर हैं।

बॉर्न-जैसा शेल शब्दावली, में $somethingकहा जाता है पैरामीटर विस्तार (भी कवर ${something#pattern}और जैसे कुछ गोले में अधिक ${array[x]}, ${param:offset}, ${x:|y}और कई और अधिक विस्तार ऑपरेटरों)।

विभिन्न प्रकार के पैरामीटर हैं:

  • चर जैसे $foo,$PATH
  • स्थितिगत मापदंड ( $1, $2... आपके स्क्रिप्ट को प्राप्त हुए तर्क)
  • अन्य विशेष मानकों की तरह $0, $-, $#, $*, $@, $$, $!, $?...

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

शेल के आधार पर, चर के विभिन्न प्रकार (स्केलर, एरे, हैश) हो सकते हैं या कुछ विशेष गुण दिए जा सकते हैं (केवल पढ़ने के लिए, निर्यात, कम मामले ...)।

(जैसे वे चर के कुछ खोल के द्वारा बनाई गई या खोल करने के लिए विशेष अर्थ नहीं होता कर रहे हैं $OPTIND, $IFS, $_...)

शेल चर जिनके पास निर्यात विशेषता होती है, स्वचालित रूप से पर्यावरण चर के रूप में निर्यात किए जाते हैं जो शेल निष्पादित करता है।

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

VAR=foo
export VAR
printenv VAR

कमांड के VARलिए एक पर्यावरण चर पारित करेंगे printenv(जो हम इसकी सामग्री को प्रिंट करने के लिए कह रहे हैं), लेकिन आप यह भी कर सकते हैं:

env VAR=foo printenv VAR

या:

perl -e '$ENV{VAR}="foo"; exec "printenv", "VAR"'

उदाहरण के लिए।

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

$ env '#+%=whatever' printenv '#+%'
whatever

गोले पर्यावरण चर को प्राप्त करेंगे जो उन्हें केवल उन चर चर के लिए प्राप्त होते हैं जिनका नाम वैध शैल चर हैं (और कुछ गोले में कुछ विशेष लोगों को अनदेखा करते हैं $IFS)।

इसलिए, जब आप 1एक कमांड के लिए एक पर्यावरण चर पारित करने में सक्षम हो जाएगा :

$ env '1=whatever' printenv 1
whatever

इसका मतलब यह नहीं है कि उस पर्यावरण चर के साथ एक शेल को कॉल करना $1पैरामीटर के मूल्य को निर्धारित करेगा :

$ env '1=whatever' sh -c 'echo "$1"' script-name foo bar
foo

3

नहीं, ये स्क्रिप्ट के पैरामीटर हैं। उदाहरण के लिए यदि आप अपनी स्क्रिप्ट को कॉल करते हैं जैसे:

mynicescript.sh one two three

फिर स्क्रिप्ट के अंदर, इन मापदंडों के रूप में उपलब्ध होगा

$1 = one
$2 = two
$3 = three

और $ 0 ही स्क्रिप्ट का नाम है।

इसलिए जब आप स्क्रिप्ट से बाहर होते हैं, तो ये चर उपलब्ध नहीं होते हैं ($ 0 को छोड़कर, जो प्रदर्शित करता है / बिन / बैश - शेल ही)।


"इसलिए जब आप स्क्रिप्ट के बाहर होते हैं, तो ये चर उपलब्ध नहीं होते हैं" आप "स्क्रिप्ट के बाहर " से क्या मतलब है , क्योंकि मैं अपने टर्मिनल में इन चर के मूल्यों को देख सकता हूं।
user7681202

2
@ user7681202: आप अपने टर्मिनल में किन लोगों को देख सकते हैं? $0आपकी वर्तमान टर्मिनल प्रक्रिया (संभावित बैश) की ओर इशारा करेगा और $?बस अंतिम प्रक्रिया का निकास कोड है।
जेसी_ब

मैंने gnome-terminalतर्कों ( gnome-terminal Hello World) के साथ चलने की कोशिश की । मैं देख सकता था $0, लेकिन मैं देख नहीं पाया $1और $2
user7681202

@Jesse_b धन्यवाद, मैंने उत्तर में $ 0 की सामग्री जोड़ी है।
जारोस्लाव कुचेरा

1
@ user7681202 सूक्ति-टर्मिनल शेल नहीं है, यह टर्मिनल एमुलेटर (जैसे xterm, konsole आदि) है। शेल टर्मिनल के अंदर चलता है और यह bash / sh / zsh / tcsh और कई और अधिक हो सकता है। स्क्रिप्ट उचित हेडर (जैसे #! / बिन / बैश) और मुखौटा में निर्दिष्ट शेल द्वारा व्याख्या करने योग्य सामग्री के साथ निष्पादन योग्य फ़ाइल है। यह आमतौर पर प्रत्यय .sh का उपयोग करता है।
जारोस्लाव कुचेरा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.