सबसे पहले, बाकी हिस्सों से अलग zsh। यह पुराने बनाम आधुनिक गोले की बात नहीं है: zsh अलग तरह से व्यवहार करता है। Zsh डिजाइनरों ने पारंपरिक गोले (बॉर्न, ksh, बैश) के साथ इसे असंगत बनाने का फैसला किया, लेकिन उपयोग करने में आसान है।
दूसरा, जब जरूरत हो तो याद रखना की तुलना में हर समय दोहरे उद्धरण चिह्नों का उपयोग करना कहीं अधिक आसान है। वे समय की सबसे अधिक जरूरत होती है, इसलिए आपको जरूरत पड़ने पर सीखने की जरूरत होगी, न कि जरूरत पड़ने पर।
संक्षेप में, दोहरे उद्धरण आवश्यक हैं जहाँ भी शब्दों की एक सूची या एक पैटर्न अपेक्षित है । वे संदर्भों में वैकल्पिक हैं जहां पार्सर द्वारा एक कच्ची स्ट्रिंग की उम्मीद की जाती है।
बिना उद्धरण के क्या होता है
ध्यान दें कि दोहरे उद्धरण चिह्नों के बिना, दो चीजें होती हैं।
- सबसे पहले, विस्तार का परिणाम (जैसे पैरामीटर प्रतिस्थापन के लिए चर का मूल्य
${foo}
, या जैसे कमांड प्रतिस्थापन के लिए कमांड का आउटपुट $(foo)
) को शब्दों में विभाजित किया जाता है जहां भी यह व्हाट्सएप होता है।
अधिक सटीक रूप से, विस्तार का परिणाम प्रत्येक वर्ण पर विभाजित होता है जो IFS
चर (विभाजक वर्ण) के मूल्य में प्रकट होता है । यदि विभाजक वर्णों के अनुक्रम में व्हाट्सएप (स्पेस, टैब या न्यूलाइन) होता है, तो व्हॉट्सएप को एकल वर्ण के रूप में गिना जाता है; अग्रणी, अनुगामी या बार-बार गैर-व्हाट्सएप विभाजक खाली क्षेत्रों की ओर ले जाते हैं। उदाहरण के लिए, के साथ IFS=" :"
, :one::two : three: :four
रिक्त फ़ील्ड से पहले पैदा करता है one
, के बीच one
और two
के बीच, और (एक भी एक) three
और four
।
- विभाजन के परिणामस्वरूप होने वाले प्रत्येक क्षेत्र को एक ग्लोब (एक वाइल्डकार्ड पैटर्न) के रूप में व्याख्या की जाती है यदि इसमें वर्णों में से एक होता है
\[*?
। यदि वह पैटर्न एक या अधिक फ़ाइल नामों से मेल खाता है, तो पैटर्न को मिलान फ़ाइल नामों की सूची से बदल दिया जाता है।
एक निर्विवाद चर विस्तार $foo
को बोलचाल की भाषा में "स्प्लिट + ग्लोब ऑपरेटर" के रूप में जाना जाता है, "$foo"
जिसके विपरीत बस चर का मान लेता है foo
। वही कमांड प्रतिस्थापन के लिए जाता है: "$(foo)"
एक कमांड प्रतिस्थापन है, $(foo)
एक कमांड प्रतिस्थापन है जिसके बाद विभाजन + ग्लोब होता है।
जहां आप दोहरे उद्धरण चिह्नों को छोड़ सकते हैं
यहां वे सभी मामले हैं जो मैं एक बॉर्न-शैली के खोल के बारे में सोच सकता हूं जहां आप दोहरे उद्धरण के बिना एक चर या कमांड प्रतिस्थापन लिख सकते हैं, और मूल्य की शाब्दिक व्याख्या की जाती है।
एक असाइनमेंट के दाईं ओर।
var=$stuff
a_single_star=*
ध्यान दें कि आपको दोहरे उद्धरण चिह्नों की आवश्यकता है export
, क्योंकि यह एक सामान्य बिलिन है, न कि कोई कीवर्ड। यह केवल कुछ गोले जैसे कि डैश, zsh (sh emulation में), यश या पॉश में सही है; bash और ksh दोनों export
विशेष रूप से व्यवहार करते हैं ।
export VAR="$stuff"
एक case
बयान में
case $var in …
ध्यान दें कि आपको केस पैटर्न में दोहरे उद्धरण चिह्नों की आवश्यकता है। शब्द विभाजन एक मामले के पैटर्न में नहीं होता है, लेकिन एक अयोग्य संस्करण को एक पैटर्न के रूप में व्याख्या की जाती है जबकि एक उद्धृत चर को शाब्दिक स्ट्रिंग के रूप में व्याख्या की जाती है।
a_star='a*'
case $var in
"$a_star") echo "'$var' is the two characters a, *";;
$a_star) echo "'$var' begins with a";;
esac
डबल कोष्ठक के भीतर। डबल ब्रैकेट शेल विशेष सिंटैक्स हैं।
[[ -e $filename ]]
के दाहिने हाथ की ओर: सिवाय इसके कि आप दोहरे उद्धरण चिह्नों जहां एक पैटर्न या रेगुलर एक्सप्रेशन की उम्मीद है की जरूरत है =
या ==
या !=
या =~
।
a_star='a*'
if [[ $var == "$a_star" ]]; then echo "'$var' is the two characters a, *"
elif [[ $var == $a_star ]]; then echo "'$var' begins with a"
fi
आपको एकल कोष्ठक के भीतर हमेशा की तरह दोहरे उद्धरण चिह्नों की आवश्यकता होती है [ … ]
क्योंकि वे साधारण शेल सिंटैक्स होते हैं (यह एक कमांड है जिसे कहा जाता है [
)। सिंगल या डबल ब्रैकेट देखें
गैर-इंटरैक्टिव POSIX गोले में एक पुनर्निर्देशन में (न bash
, न ही ksh88
)।
echo "hello world" >$filename
कुछ गोले, जब संवादात्मक होते हैं, तो चर के मूल्य को वाइल्डकार्ड पैटर्न के रूप में मानते हैं। POSIX गैर-संवादात्मक गोले में उस व्यवहार को प्रतिबंधित करता है, लेकिन कुछ गोले जिसमें पोश (POSIX मोड को छोड़कर) और ksh88 को शामिल किया गया है (जब यह पाया जाता है, तो (माना जाता है) sh
, जैसे कि Solaris जैसे कुछ व्यावसायिक यूनियनों का POSIX अभी भी वहां मौजूद है ( विभाजन काbash
प्रयास भी करता है ) और पुनर्निर्देशन में विफल रहता है जब तक कि विभाजन ग्लोबिंग + वास्तव में एक शब्द में परिणाम) है, जिसके कारण यह बेहतर है एक में पुनर्निर्देशन के लक्ष्य को उद्धृत करने के मामले में स्क्रिप्ट आप एक करने के लिए इसे परिवर्तित करना चाहते हैं स्क्रिप्ट कुछ दिन, या इसे चलाने के लिए एक प्रणाली पर जहां है उस बिंदु पर गैर-अनुपालन, या यह इंटरैक्टिव गोले से खट्टा हो सकता है ।sh
bash
sh
एक अंकगणितीय अभिव्यक्ति के अंदर। वास्तव में, आपको अंकगणित को एक अंकगणितीय अभिव्यक्ति के रूप में पार्स करने के लिए छोड़ने की आवश्यकता है।
expr=2*2
echo "$(($expr))"
हालाँकि, आपको अंकगणित विस्तार के आसपास उद्धरणों की आवश्यकता है क्योंकि वे अधिकांश गोले में शब्द विभाजन के अधीन हैं क्योंकि PIXIX ((!) की आवश्यकता होती है।
एक सहयोगी सरणी सबस्क्रिप्ट में।
typeset -A a
i='foo bar*qux'
a[foo\ bar\*qux]=hello
echo "${a[$i]}"
निर्विवाद चर और कमांड प्रतिस्थापन कुछ दुर्लभ परिस्थितियों में उपयोगी हो सकता है:
- जब परिवर्तनीय मूल्य या कमांड आउटपुट में ग्लोब पैटर्न की एक सूची होती है और आप इन पैटर्नों का मिलान फाइलों की सूची में करना चाहते हैं।
- जब आप जानते हैं कि मूल्य में कोई वाइल्डकार्ड वर्ण नहीं है, तो
$IFS
इसे संशोधित नहीं किया गया था और आप इसे व्हाट्सएप वर्णों में विभाजित करना चाहते हैं।
- जब आप किसी निश्चित वर्ण पर एक मान विभाजित करना चाहते हैं: ग्लोबिंग को अक्षम करें
set -f
, IFS
विभाजक वर्ण पर सेट करें (या इसे व्हाट्सएप पर विभाजित करने के लिए अकेला छोड़ दें), फिर विस्तार करें।
Zsh
Zsh में, आप कुछ अपवादों के साथ, अधिकांश समय दोहरे उद्धरण छोड़ सकते हैं।
$var
कभी भी कई शब्दों का विस्तार नहीं होता है, हालाँकि यह खाली सूची (एकल, खाली शब्द से युक्त सूची के विपरीत) के लिए फैलता है यदि var
रिक्त स्ट्रिंग का मान है। कंट्रास्ट:
var=
print -l $var foo # prints just foo
print -l "$var" foo # prints an empty line, then foo
इसी प्रकार, "${array[@]}"
सरणी के सभी तत्वों तक $array
फैल जाता है , जबकि केवल गैर-खाली तत्वों तक फैलता है।
@
पैरामीटर विस्तार ध्वज कभी कभी पूरी प्रतिस्थापन को दोहरे उद्धरण चिह्नों की आवश्यकता है: "${(@)foo}"
।
कमांड प्रतिस्थापन क्षेत्र को विभाजित करता है यदि अयोग्य है: echo $(echo 'a'; echo '*')
प्रिंट a *
(एक ही स्थान के साथ) जबकि echo "$(echo 'a'; echo '*')"
अनमॉडिफाइड दो-लाइन स्ट्रिंग प्रिंट करता है। "$(somecommand)"
एक शब्द, अंतिम अंतिम समाचारों में कमांड का आउटपुट प्राप्त करने के लिए उपयोग करें । "${$(somecommand; echo _)%?}"
अंतिम newlines सहित कमांड का सटीक आउटपुट प्राप्त करने के लिए उपयोग करें । "${(@f)$(somecommand)}"
कमांड के आउटपुट से सरणी की एक पंक्ति प्राप्त करने के लिए उपयोग करें ।
SH_WORD_SPLIT
विकल्प से प्रभावित होता है।