बैश में सिंगल और डबल कोट्स के बीच अंतर


567

बैश में, सिंगल कोट्स ( '') और डबल कोट्स ( "") के बीच क्या अंतर हैं ?


1
यह भी देखें (एक संभावित क्रॉस-साइट डुप्लिकेट): "...", '...', $ '...' और "$" ... के बीच क्या अंतर है? से यूनिक्स और लिनक्स स्टैक एक्सचेंज
रगड़

जवाबों:


576

सिंगल कोट्स कुछ भी इंटरपोल नहीं करेंगे, लेकिन डबल कोट्स करेंगे। उदाहरण के लिए: चर, बैकटिक्स, कुछ \बच, आदि।

उदाहरण:

$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")

बाश मैनुअल में यह कहना है:

3.1.2.2 एकल उद्धरण

एकल उद्धरणों में वर्ण जोड़ना ( ') उद्धरणों के भीतर प्रत्येक वर्ण के शाब्दिक मूल्य को संरक्षित करता है। एकल उद्धरण के बीच एक एकल उद्धरण नहीं हो सकता है, तब भी जब एक बैकस्लैश द्वारा पूर्ववर्ती हो।

3.1.2.3 डबल कोट्स

दोहरे उद्धरण चिह्नों में पात्रों संलग्न ( ") उद्धरण के भीतर सभी पात्रों का शाब्दिक मूल्य को बरकरार रखता है, के अपवाद के साथ $, `, \, और, जब इतिहास विस्तार सक्षम किया गया है, !। अक्षर $और `दोहरे उद्धरण ( शैल विस्तार देखें ) के भीतर अपने विशेष अर्थ को बरकरार रखते हैं । जब निम्न पात्रों में से एक के बाद बैकस्लैश केवल अपने विशेष अर्थ को बरकरार रखे हुए: $, `, ",\, या न्यूलाइन। दोहरे उद्धरण चिह्नों के भीतर, इन वर्णों में से एक के बाद बैकस्लैश हटा दिए जाते हैं। बैकस्लैश एक विशेष अर्थ के बिना पूर्ववर्ती वर्णों को अनमॉडिफाइड छोड़ दिया जाता है। एक दोहरे उद्धरण को दोहरे उद्धरण के भीतर उद्धृत किया जा सकता है। यदि सक्षम किया गया है, तो इतिहास विस्तार तब तक किया जाएगा जब तक कि !दोहरे उद्धरण चिह्नों में एक बैकस्लैश का उपयोग करके भाग न जाए। बैकस्लैश पूर्ववर्ती को !हटाया नहीं गया है।

विशेष मापदंडों *और @विशेष अर्थ है जब दोहरे उद्धरण में ( शेल पैरामीटर विस्तार देखें )।


40
किसी के लिए जो "इंटरपोलेट" का मतलब नहीं जानता है: en.wikipedia.org/wiki/String_interpolation
Kolob Canyon

जब आप git_promptउस git का उपयोग कर रहे होते हैं, तो वे इसे इस तरह उपयोग करने का सुझाव देते हैं PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ', git प्रॉम्प्ट , इसके अनुसार यह काम नहीं करना चाहिए। क्या PS#चर के बारे में कुछ खास है ? या यह काम क्यों करता है अगर यह प्रक्षेप नहीं कर रहा है।
इकिम

@ekiim यह सटीक पाठ सेट (अपरिवर्तित) है PS1echo $PS1मेरा मतलब देखने की कोशिश करो । लेकिन PS1प्रदर्शित होने से पहले मूल्यांकन किया जाता है ( PROMPTINGbash manpage में अनुभाग देखें )। इसका परीक्षण करने के लिए, प्रयास करें PS1='$X'। आपके पास कोई संकेत नहीं होगा। तब चलाने X=fooऔर अचानक आपके शीघ्र "foo" (था PS1जब मूल्यांकन किया गया है सेट के बजाय प्रदर्शित किया यदि फिर भी शीघ्र होता है)।
एडम बैटकिन

262

स्वीकार किए जाते हैं जवाब बहुत अच्छा है। मैं एक तालिका बना रहा हूं जो विषय की त्वरित समझ में मदद करता है। स्पष्टीकरण में एक सरल चर और aसाथ ही अनुक्रमित सरणी शामिल है arr

अगर हम सेट करते हैं

a=apple      # a simple variable
arr=(apple)  # an indexed array with a single element

और फिर echoदूसरे कॉलम में अभिव्यक्ति, हमें तीसरे कॉलम में दिखाया गया परिणाम / व्यवहार मिलेगा। चौथा स्तंभ व्यवहार की व्याख्या करता है।

 # | Expression  | Result      | Comments
---+-------------+-------------+--------------------------------------------------------------------
 1 | "$a"        | apple       | variables are expanded inside ""
 2 | '$a'        | $a          | variables are not expanded inside ''
 3 | "'$a'"      | 'apple'     | '' has no special meaning inside ""
 4 | '"$a"'      | "$a"        | "" is treated literally inside ''
 5 | '\''        | **invalid** | can not escape a ' within ''; use "'" or $'\'' (ANSI-C quoting)
 6 | "red$arocks"| red         | $arocks does not expand $a; use ${a}rocks to preserve $a
 7 | "redapple$" | redapple$   | $ followed by no variable name evaluates to $
 8 | '\"'        | \"          | \ has no special meaning inside ''
 9 | "\'"        | \'          | \' is interpreted inside "" but has no significance for '
10 | "\""        | "           | \" is interpreted inside ""
11 | "*"         | *           | glob does not work inside "" or ''
12 | "\t\n"      | \t\n        | \t and \n have no special meaning inside "" or ''; use ANSI-C quoting
13 | "`echo hi`" | hi          | `` and $() are evaluated inside ""
14 | '`echo hi`' | `echo hi`   | `` and $() are not evaluated inside ''
15 | '${arr[0]}' | ${arr[0]}   | array access not possible inside ''
16 | "${arr[0]}" | apple       | array access works inside ""
17 | $'$a\''     | $a'         | single quotes can be escaped inside ANSI-C quoting
18 | "$'\t'"     | $'\t'       | ANSI-C quoting is not interpreted inside ""
19 | '!cmd'      | !cmd        | history expansion character '!' is ignored inside ''
20 | "!cmd"      | cmd args    | expands to the most recent command matching "cmd"
21 | $'!cmd'     | !cmd        | history expansion character '!' is ignored inside ANSI-C quotes
---+-------------+-------------+--------------------------------------------------------------------

यह सभी देखें:


1
स्वीकृत उत्तर अंत में कहता है कि परिणाम The special parameters * and @ have special meaning when in double quotesकैसे आए ? "*"*
anddero

2
@ कार्ल-एंडेरोमेरे, क्योंकि वे उस मामले में पैरामीटर के रूप में विस्तारित नहीं हैं। "$@"और "$*"पैरामीटर विस्तार हैं। "@"और "*"नहीं हैं।
चार्ल्स डफी

@CharlesDuffy धन्यवाद, यह अब समझ में आता है!
anddero

3
नंबर 9, echo "\'"मुझे लौटाता है \'
मैक्सगाइवर

@MaxGyver: इसे इंगित करने के लिए धन्यवाद। मैंने जवाब अपडेट कर दिया है।
कोडवर्ड

233

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

उदाहरण के लिए, यह

#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'

यह दे देंगे:

double quotes gives you sometext
single quotes gives you $MYVAR

11

दूसरों ने बहुत अच्छी तरह से समझाया और केवल सरल उदाहरणों के साथ देना चाहते हैं।

शेल के चारों ओर सिंगल कोट्स का उपयोग किसी विशेष वर्ण की व्याख्या करने से शेल को रोकने के लिए किया जा सकता है। डॉलर के संकेत, रिक्त स्थान, ampersands, तारांकन और अन्य विशेष वर्ण सभी को अनदेखा किया जाता है जब एकल उद्धरण के भीतर संलग्न होते हैं।

$ echo 'All sorts of things are ignored in single quotes, like $ & * ; |.' 

यह यह देगा:

All sorts of things are ignored in single quotes, like $ & * ; |.

केवल एक चीज जो एकल उद्धरणों में नहीं डाली जा सकती, वह एकल उद्धरण है।

डबल कोट्स दोहरे उद्धरण चिह्नों को छोड़कर एकल उद्धरण के समान कार्य करते हैं, फिर भी शेल को डॉलर के संकेतों, पीछे के उद्धरण और बैकस्लैश की व्याख्या करने की अनुमति देते हैं। यह पहले से ही ज्ञात है कि बैकस्लैश एक विशेष चरित्र को व्याख्या करने से रोकते हैं। यह दोहरे उद्धरण चिह्नों के भीतर उपयोगी हो सकता है यदि किसी डॉलर चिन्ह को एक चर के बजाय पाठ के रूप में उपयोग करने की आवश्यकता हो। यह दोहरे उद्धरण चिह्नों से बचने की भी अनुमति देता है, इसलिए उन्हें उद्धृत स्ट्रिंग के अंत के रूप में व्याख्या नहीं की जाती है।

$ echo "Here's how we can use single ' and double \" quotes within double quotes"

यह यह देगा:

Here's how we can use single ' and double " quotes within double quotes

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

$ echo "The current Oracle SID is $ORACLE_SID"

यह यह देगा:

The current Oracle SID is test

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

$ today=`date '+%A, %B %d, %Y'`
$ echo $today 

यह यह देगा:

Monday, September 28, 2015 

3

वहाँ के उपयोग के बीच स्पष्ट अंतर है ' 'और " "

जब ' 'किसी भी चीज का उपयोग किया जाता है, तो कोई "परिवर्तन या अनुवाद" नहीं किया जाता है। जैसा है वैसा ही छपा है।

इसके साथ " ", जो भी इसे घेरता है, उसका "अनुवाद या रूपांतरण" इसके मूल्य में होता है।

अनुवाद / परिवर्तन से मेरा मतलब निम्नलिखित है: एकल उद्धरणों के भीतर कुछ भी उनके मूल्यों के लिए "अनुवादित" नहीं होगा। उन्हें उद्धरण के अंदर ले जाया जाएगा। उदाहरण: a=23है, तो echo '$a'उत्पादन करेगा $aमानक आउटपुट पर। जबकि echo "$a"उत्पादन करेगा 23मानक आउटपुट पर।


1
"अनुवाद" या "परिवर्तन" से आपका क्या अभिप्राय है?
निको हसे

यह उत्तर काफी भ्रामक है और यह मौजूदा अच्छे उत्तरों के शीर्ष पर कुछ भी नहीं जोड़ता है।
कोडवर्डर

2
यह अत्यधिक संक्षिप्त होने के बिना मेरी राय में एक संक्षिप्त संक्षिप्त जवाब था जो मेरे लिए समझना आसान था। अनुवाद / परिवर्तन कहते समय वे दोहरे उद्धरण-चिह्नों का विस्तार करेंगे जहां एकल उद्धरण चर का विस्तार नहीं करेंगे।
B_e_n_n_y_

1
हां, यह सबसे अच्छा जवाब है। यह स्वीकृत उत्तर होना चाहिए।
जेमी किर्बी

3

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

bashखोल दो तरीके गणित आपरेशन कर का समर्थन करता है, एक से परिभाषित किया गया निर्मित letकमान और $((..))ऑपरेटर। पूर्व एक अंकगणितीय अभिव्यक्ति का मूल्यांकन करता है जबकि उत्तरार्द्ध एक यौगिक कथन का अधिक होता है।

यह समझना महत्वपूर्ण है कि अंकगणित का उपयोग letशब्द-विभाजन, पथनाम विस्तार के साथ किसी भी अन्य शेल कमांड की तरह किया जाता है। इसलिए उचित उद्धरण और भागने की जरूरत है।

उपयोग करते समय यह उदाहरण देखें let

let 'foo = 2 + 1'
echo $foo
3

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

bar=1
let 'foo = $bar + 1'

बुरी तरह से विफल हो जाएगा, के रूप में $barएकल उद्धरण के तहत विस्तार नहीं होगा और के रूप में डबल-उद्धृत किया जाना चाहिए

let 'foo = '"$bar"' + 1'

यह एक कारण $((..))होना चाहिए, हमेशा उपयोग करने पर विचार किया जाना चाहिए let। क्योंकि इसके अंदर, सामग्री शब्द-विभाजन के अधीन नहीं है। पिछले उदाहरण का उपयोग करके letबस के रूप में लिखा जा सकता है

(( bar=1, foo = bar + 1 ))

हमेशा $((..))एक उद्धरण के बिना उपयोग करने के लिए याद रखें

यद्यपि इसे $((..))दोहरे-उद्धरणों के साथ उपयोग किया जा सकता है, इसका कोई उद्देश्य नहीं है क्योंकि इसके परिणाम में ऐसी सामग्री नहीं हो सकती है जिसे दोहरे-उद्धरण की आवश्यकता होगी। बस यह सुनिश्चित करें कि यह एकल उद्धृत नहीं है।

printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2

हो सकता है कि किसी $((..))एक उद्धृत स्ट्रिंग के अंदर ऑपरेटर का उपयोग करने के कुछ विशेष मामलों में , आपको उद्धरणों को एक तरह से प्रक्षेपित करने की आवश्यकता हो, जो ऑपरेटर या तो छोड़ दिया गया हो या दोहरे उद्धरणों के तहत। उदाहरण के लिए एक मामले पर विचार करें, जब आप curlकिसी अनुरोध के बाद हर बार काउंटर पास करने के लिए एक बयान के अंदर ऑपरेटर का उपयोग करने के लिए बांध रहे हैं

curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'

अंदर नेस्टेड डबल-कोट्स के उपयोग पर ध्यान दें, जिसके बिना शाब्दिक स्ट्रिंग $((reqcnt++))को requestCounterक्षेत्र में पारित किया जाता है ।


2
चार्ल्स डफी यहाँ दोहरे उद्धरण के लिए भी एक अच्छा मामला बनाते हैं $((...))। यह "थोड़ा" पागल हो सकता है और IFS=0उदाहरण के लिए काफी संभावना नहीं है , लेकिन यह निश्चित रूप से असंभव नहीं है :)
पेसा

विरासत का $[[...]]सिंटैक्स भी है लेकिन शायद आप इसे भूलने में सही थे।
त्रिवेणी २ tri
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.