बैश वैरिएबल को आरम्भ करना - क्या यह आवश्यक है, अनुशंसा की जाती है या आप जाते समय परिभाषित करते हैं


9

क्या स्क्रिप्ट में बैश वैरिएबल के मूल्य को शुरू करने का कोई फायदा / नुकसान है, या तो मुख्य कोड से पहले या स्थानीय वेरिएबल्स को वास्तविक मूल्य बताने से पहले?

क्या मुझे ऐसा कुछ करने की आवश्यकता है:

init()
{
    name=""
    name=$1
}

init "Mark"

क्या कचरे के मूल्यों (यदि आरंभीकृत नहीं किया गया है) के साथ चर का कोई जोखिम है और चर के मूल्यों का नकारात्मक प्रभाव है?


2
आपको यह विचार कहां से मिला?

6
@DoritoStyle खैर, अगर किसी को C के रूप में निम्न स्तर की भाषाओं के लिए उपयोग किया जाता है, तो यह चिंतित होने के लिए एक पूरी तरह से वैध बात है।
Kusalananda

@ कुसलानंद सी उस कोड के बराबर नहीं है name = ""; name = argv[1];? और क्या यह व्यर्थ नहीं है?
जोसेफ सिबल-रिनेटेट मोनिका

1
@ जोसेफिबल-रीनस्टोमोनिका हाँ। आपके द्वारा पोस्ट किया गया C कोड व्यर्थ है। सी में, हालांकि, शेल में विरोध के रूप में, अनइंस्टॉल किए गए चर में विशेष रूप से अच्छी तरह से परिभाषित मूल्य नहीं है। इसका मतलब यह है कि C जैसी भाषाओं में वैरिएबल को शुरू करना कई परिस्थितियों में समझ में आता है। शेल में ऐसा करने की जरूरत नहीं है। सी में केवल एक चर को शुरू करने से इसे तुरंत दूसरे मूल्य पर सेट करना व्यर्थ है, जैसा कि आप बताते हैं।
Kusalananda

जवाबों:


22

एक चर को एक खाली स्ट्रिंग निर्दिष्ट करने के लिए कोई लाभ नहीं है और फिर तुरंत इसे एक और चर स्ट्रिंग प्रदान करने के लिए। शेल चर के लिए मान का असाइनमेंट पूरी तरह से इसके पिछले मूल्य को अधिलेखित कर देगा।

मेरी जानकारी में कोई सिफारिश नहीं है जो कहती है कि आपको खाली तारों के लिए चर को स्पष्ट रूप से प्रारंभ करना चाहिए। वास्तव में, ऐसा करने से कुछ परिस्थितियों में त्रुटियाँ हो सकती हैं (यदि नीचे चल रही है तो त्रुटियां स्पष्ट रूप से स्पष्ट होंगी set -u)।

स्क्रिप्ट के शुरू होने के बाद से अप्रयुक्त चर, या उस unsetपर कमांड चलाने से स्पष्ट रूप से परेशान होने का कोई मूल्य नहीं होगा। इस तरह के एक चर का मूल्य कुछ भी नहीं होगा। यदि इसका उपयोग किया जाता है "$myvariable", तो आपको इसके बराबर मिलेगा "", और आपको कभी भी "कचरा डेटा" नहीं मिलेगा।

यदि शेल विकल्प या nounsetतो के साथ सेट किया गया है , तो एक अस्थिर वैरिएबल को संदर्भित करने से शेल को एक त्रुटि उत्पन्न होगी (और एक गैर-इंटरैक्टिव शेल समाप्त हो जाएगा):set -o nounsetset -u

$ set -u
$ echo "$myvariable"
/bin/sh: myvariable: parameter not set

या में bash:

$ set -u
$ echo "$myvariable"
bash: myvariable: unbound variable

शेल वेरिएबल को पर्यावरण द्वारा आरम्भ किया जाएगा यदि चर का नाम किसी मौजूदा पर्यावरण चर से मेल खाता है।

यदि आप उम्मीद करते हैं कि आप एक ऐसे चर का उपयोग कर रहे हैं जो पर्यावरण द्वारा इस तरह से शुरू किया जा सकता है (और यदि यह अवांछित है), तो आप अपनी स्क्रिप्ट के मुख्य भाग से पहले इसे स्पष्ट रूप से अनसेट कर सकते हैं:

unset myvariable    # unset so that it doesn't inherit a value from the environment

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

आप शेल वेरिएबल में अनइंस्टाल्यूटेड कचरा कभी नहीं मारेंगे (जब तक कि, जैसा कि कहा गया है, कि कचरा पहले से ही एक ही नाम से एक पर्यावरण चर में मौजूद है)।


3
जबकि एक चर को खाली मान पर सेट करने के लिए कोई मूल्य नहीं है और फिर इसे ओपी के रूप में तुरंत सेट किया जाता है, परिकलित करने के लिए इसे सेट करने के लिए unsetकिसी प्रकार forया whileलूप को चलाने से पहले एक खाली मान (या टिंग) सेट करने में मूल्य होता है। यदि कोई शर्त है कि लूप वास्तव में स्थिति (नों) के पूरा नहीं होने के कारण नहीं चलेगा; और हो सकता है कि वेरिएबल लिपि को विरासत में मिले परिवेश में किसी अन्य मूल्य पर सेट किया गया हो। लेकिन यकीनन बेहतर है कि सबकुछ डाल दिया जाए main()और चरों को परिभाषित किया जाए local
मोंटी हार्डर

आप पैरामीटर विस्तार संचालकों के उपयोग से भी परेशान चर का पता लगा सकते हैं :, जैसे कि${myvariable-defaultvalue}
बर्मार

3

संपादित करें : वूप्स, जाहिरा तौर पर घोषणा आरंभीकरण से अलग है। मैं इसे यहाँ वैसे भी छोड़ दूँगा ताकि नौसिखिए कोडर जैसे खुद मेरी गलती से सीख सकें।


किसी फ़ंक्शन में स्थानीय चर घोषित करने का लाभ यह है कि आप आसानी से कोड कॉपी कर सकते हैं।

उदाहरण के लिए, मान लें कि मेरे पास एक फ़ंक्शन है:

foo(){
    local name
    name="$1"
    echo "$name"
}

अगर मैं इसे एक स्क्रिप्ट में बनाना चाहता हूं, तो मैं सिर्फ localबयान को नजरअंदाज करता हूं और बाकी सभी चीजों को कॉपी करता हूं :

#!/bin/bash
name="$1"
echo "$name"

यदि घोषणा और असाइनमेंट एक ही पंक्ति में थे, तो मुझे localस्क्रिप्ट में बदलने से पहले मैन्युअल रूप से भाग को संपादित करना होगा :

foo(){
    local name="$1"
    echo "$name"
}

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


1
सवाल घोषणा और संयोजन के संयोजन के बारे में नहीं था। यह इस बारे में था कि वास्तविक मूल्य निर्दिष्ट करने से पहले एक खाली मान के साथ आरंभ करना है या नहीं।
बरमार

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