शेल स्क्रिप्ट में चर का संदर्भ देना


10

शेल स्क्रिप्ट में, अगर मैं एक चर को परिभाषित करता हूं जैसे कि FOO=25, क्या इसे संदर्भित करने $FOO$और के बीच अंतर है ${FOO}$?


2
आपको $अंत में उपयोग नहीं करना चाहिए ! इसे सामान्य चरित्र के रूप में माना जाएगा न कि चर नाम के भाग के रूप में।
बाइट कमांडर

जवाबों:


16

अधिकांश स्थितियों में दोनों $varऔर ${var}एक ही हैं। (ध्यान दें कि आपको $अंत में उपयोग नहीं करना चाहिए !)

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

उदाहरण:

var=hel
echo ${var}lo

उत्पादन होगा hello


11

आपके मुख्य प्रश्न का उत्तर देने के लिए, "पैरामीटर विस्तार"${foo} कहा जाता है । सटीक होने के लिए, स्वयं पैरामीटर विस्तार शुरू करता है, वास्तव में पोसिक्स विनिर्देश के अनुसार वैकल्पिक हैं , लेकिन चर के नाम के अंत को इंगित करने के लिए उपयोगी हो सकता है:${ }

$ foo="bar"
$ echo $fooBaz   ## fails, no variable named $fooBaz exists

$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz

मूल रूप से, $fooऔर ${foo}समान हैं। उपरोक्त जैसे मामलों के अलावा या जब आप स्ट्रिंग हेरफेर कर रहे हैं, तो वे पूरी तरह से बराबर हैं।

हालाँकि, आपको वास्तव में उनमें से किसी का भी उपयोग नहीं करना चाहिए। अंगूठे का नियम है कि, बहुत कुछ अपवादों के साथ, आप चाहिए हमेशा का उपयोग "$foo"या "${foo}"और कभी नहीं $fooया ${foo}। आपको विभाजन + ग्लोब ऑपरेटर (उस पर बाद में) को लागू करने से बचने के लिए हमेशा अपने चर को उद्धृत करना चाहिए। आप निश्चित रूप से नहीं चाहते हैं $foo$। अंतिम $अप्रासंगिक है:

$ foo="bar"
$ echo "$foo$"
bar$

इसलिए, जबकि निर्विवाद चर कभी-कभी ठीक होते हैं:

$ echo $foo
bar

वे आमतौर पर नहीं हैं और वास्तव में बचा जाना चाहिए:

$ if [ -n $foo ]; then echo empty; else echo "not empty"; fi ## fails
empty

$ if [ -n "$foo" ]; then echo empty; else echo "not empty"; fi ## works
not empty

ध्यान दें कि कोष्ठक यहाँ भी मदद नहीं करते हैं:

$ if [ -n ${foo} ]; then echo empty; else echo "not empty"; fi  ## fails
empty

$ if [ -n "${foo}" ]; then echo empty; else echo "not empty"; fi ## works
not empty

जब आप उपयोग करते हैं $fooया ${foo}, शेल व्हाट्सएप पर चर में सहेजे गए मूल्य को विभाजित करेगा (इसे IFSचर को किसी अन्य चीज़ में सेट करके बदला जा सकता है) और फिर सूची में, प्रत्येक तत्व को एक ग्लोब पैटर्न के रूप में माना जाता है और इसमें विस्तारित किया जाता है किसी भी मिलान फाइल या निर्देशिका। इसे स्प्लिट + ग्लोब ऑपरेटर के रूप में जाना जाता है । वर्णन करने के लिए, दो फ़ाइलों वाली एक निर्देशिका पर विचार करें:

$ ls -l
-rw-r--r-- 1 terdon terdon 0 Oct  9 18:16 file1
-rw-r--r-- 1 terdon terdon 0 Oct  9 18:16 file2

अब, इसके लिए एक चर सेट करते हैं foo *:

$ foo="foo *"

यदि हम यह जाँचने का प्रयास करते हैं कि क्या उस नाम की कोई फ़ाइल मौजूद है तो क्या होगा?

$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists

चर को fooऔर में विभाजित किया गया था *, क्योंकि *एक वाइल्डकार्ड है जो किसी भी स्ट्रिंग से मेल खाता है, शेल आपको बताता है कि foo *एक्सएक्सिस्ट नामक एक फ़ाइल । हालाँकि, अगर हम इसे सही ढंग से उद्धृत करते हैं, तो ऐसा नहीं होता है:

$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file

इस बिंदु को चित्रित करने के लिए यह एक तुच्छ उदाहरण था। कल्पना कीजिए कि क्या मैंने हालांकि rmइसके बजाय इस्तेमाल किया था echo

तो, पहला नियम: हमेशा अपने चर का उद्धरण करें। आप "$foo"या तो इसका उपयोग कर सकते हैं या "${foo}"इसे किसी भी तरह से उद्धृत कर सकते हैं । चर का सुरक्षित रूप से उपयोग करने के बारे में अधिक जानकारी के लिए, इन पोस्टों पर एक नज़र डालें:


मैं आपके अन्यथा उत्कृष्ट उत्तर को संपादित नहीं करना चाहता था, लेकिन ऐसा नहीं $ var="foo *"होना चाहिए $ foo="foo *"? आप varकहीं भी उपयोग नहीं करते हैं ।
जो

@ जो ओह, अच्छा दु: ख! हां, निश्चित रूप से इसे इंगित करने के लिए धन्यवाद देना चाहिए। जिस तरह से एक संपादन का सुझाव देकर ऐसी गलतियों को ठीक करने के लिए स्वतंत्र महसूस करें। इस तरह की बात बहुत प्रोत्साहित करती है, ठीक इसी तरह मूर्खतापूर्ण त्रुटियों से बचने के लिए।
टेराडन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.