"...", '...', $ '...', और $ "..." उद्धरणों में क्या अंतर है?


49

कभी कभी मैं स्क्रिप्ट कुछ पाठ के हवाले से इन अलग अलग तरीकों का उपयोग देखें: "...", '...', $'...', और $"..."। क्यों कई अलग-अलग प्रकार के उद्धरण का उपयोग किया जा रहा है?

क्या वे अलग तरह से व्यवहार करते हैं या प्रभावित करते हैं कि मैं उनके अंदर क्या कर सकता हूं?


1
संभावित क्रॉस-साइट डुप्लिकेट। यह उत्तर सभी विभिन्न प्रकार के उद्धरणों के शब्दार्थ (या लिंक) का सारांश प्रदान करता है।
चेपनर

जवाबों:


66

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

संक्षेप में:

  • '...' पूरी तरह से शाब्दिक है।
  • "..." दोनों चर और एम्बेडेड बोली वर्णों की अनुमति देता है।
  • $'...'चरित्र की तरह भागता है \n, लेकिन चर का विस्तार नहीं करता है।
  • $"..." बश और ksh में मानव-भाषा अनुवाद के लिए है।

'एकल कोट'

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

इन सभी उदाहरणों के परिणामस्वरूप शाब्दिक रूप से उद्धरणों के बीच क्या लिखा जाता है:

'hello world'                     => hello world
'/pkg/bin:$PATH'                  => /pkg/bin:$PATH
'hello\nworld'                    => hello\nworld
'`echo abc`'                      => `echo abc`
'I\'dn\'t've'                     => I\dn'tve

अंतिम एक जटिल है - कुछ एकल पाठ के साथ दो एकल-उद्धृत तार एक साथ चलते हैं। पहले वाले में शामिल है I\। निर्विवाद पाठ dn\'tमें एक एकल उद्धरण होता है जो शेल स्तर पर बच जाता है , इसलिए यह एक उद्धृत स्ट्रिंग शुरू नहीं करता है और इसे शाब्दिक वर्ण (इसलिए, dn't) के रूप में शामिल किया जाता है । अंतिम उद्धृत स्ट्रिंग सिर्फ है ve। उन सभी को एक ही शब्द में एक साथ चलाया जाता है जिस तरह से शेल काम करता है।

शाब्दिक पाठ और चर के संयोजन के लिए कुछ हद तक सामान्य मुहावरे उन्हें एक साथ चलाने के लिए है:

'let x="'$PATH\"

में परिणाम होगा

let x="/usr/bin:/bin"

किसी एक शब्द के रूप में (दोहरे-उद्धरण के $PATHसाथ - साथ केवल मामले में बेहतर - रिक्त स्थान या चर मान में ग्लोबिंग वर्ण अन्यथा संसाधित किए जा सकते हैं - लेकिन एक पठनीय चल उदाहरण के लिए जो मैंने नहीं किया है)।


"डबल उद्धरण"

दोहरे उद्धरण चिह्नों के अंदर, दो प्रकार के विस्तार को संसाधित किया जाता है, और आप विस्तार से बचने या संसाधित होने से बचने के लिए वर्णों से बचने के लिए बैकस्लैश का उपयोग कर सकते हैं।

विस्तार की दो श्रेणियां हैं जो दोहरे उद्धरण चिह्नों के अंदर होती हैं:

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

इनमें से कुछ उदाहरण पहले अलग तरह से काम करते हैं, और कुछ नहीं करते हैं:

"hello world"                     => hello world
"/pkg/bin:$PATH"                  => /pkg/bin:/bin:/usr/bin
"hello\nworld"                    => hello\nworld
"hello\\nworld"                   => hello\nworld
"`echo abc`"                      => abc
"I\'dn\'t've"                     => I\'dn\'t've
"I'dn't've"                       => I'dn't've
"I\"dn\"t've"                     => I"dn"t've

$ 'एएनएसआई-सी उद्धृत'

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

यह ksh से एक विस्तार है, जो अब Bash, zsh और कुछ अन्य शेल में भी समर्थित है। यह अभी तक POSIX मानक का हिस्सा नहीं है और इसलिए अधिकतम-पोर्टेबल स्क्रिप्ट इसका उपयोग नहीं कर सकते, लेकिन एक बैश या ksh स्क्रिप्ट के लिए स्वतंत्र है।

: इन पलायन के सभी उनके सी अर्थ के साथ इस्तेमाल किया जा सकता \a, \b, \f, \n, \r, \t, \v, और शाब्दिक पलायन \\, \', \", और \?। वे एक्सटेंशन \e(एस्केप कैरेक्टर) और बाश और क्श में \cx(क्या Ctrl-x द्वारा दर्ज किया जाएगा , उदाहरण के \cMलिए गाड़ी वापसी है) का समर्थन करते हैं। गोले अपने स्वयं के मामूली विस्तार की एक सीमा है।

यह चार प्रकार के जेनेरिक चरित्र से बचने की भी अनुमति देता है:

  • \nnn, अष्ट मान nnn के साथ एक एकल बाइट
  • \xHH, हेक्साडेसिमल मूल्य एचएच के साथ एक एकल बाइट
  • \uHHHHयूनिकोड कोडपॉइंट जिसका हेक्साडेसिमल इंडेक्स HHHH है
  • \UHHHHHHHHयूनिकोड कोडपॉइंट जिसका हेक्साडेसिमल इंडेक्स HHHHHHHH है

वे सभी अंक पहले वाले के बाद वैकल्पिक हैं।

$और `इसका कोई अर्थ नहीं है और ये शाब्दिक रूप से संरक्षित हैं, इसलिए आप इसमें एक चर शामिल नहीं कर सकते हैं।

$'hello world'                    => hello world
$'/pkg/bin:$PATH'                 => /pkg/bin:$PATH
$'hello\nworld'                   => hello
                                     world
$'`echo abc`'                     => `echo abc`
$'I\'dn\'t\'ve'                   => I'dn't've
$'\U1f574\u263A'                  => 🕴☺

इन पलायन के अधिकांश आप उपयोग कर अनुकरण कर सकते हैं आदेश , हालांकि POSIX केवल आवश्यकता है , , , , , , , , और वहाँ काम करने के लिए। यदि आवश्यक हो तो आप अंदर के दोहरे उद्धरण चिन्हों को एम्बेड करने के लिए कमांड प्रतिस्थापन का उपयोग कर सकते हैं :।printf\\\a\b\f\n\r\t\v\nnnprintf"Path:$(printf '\t')$PATH"


$ "लोकेल अनुवाद"

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

आप शायद इस एक का उपयोग नहीं करना चाहते हैं, लेकिन यदि आप इसे देखते हैं तो आप इसे सामान्य रूप से दोहरे उद्धरण चिह्नों के रूप में मान सकते हैं।


ध्यान देने वाली बात यह है कि किसी भी प्रकार का उद्धरण नहीं है, जो दोनों एम्बेडेड पैरामीटर विस्तार और एम्बेडेड वर्ण से बचने की अनुमति देता है। ज्यादातर मामलों में जहां आप चाहते हैं कि, आप का उपयोग करना बेहतर (सुरक्षित) होगा printf:

printf 'New path: \e[1m%s\e[0m' "/pkg/bin:$PATH:"

यह स्पष्ट रूप से अलग करता है कि कौन से हिस्से चरित्र से बचने के अधीन हैं और कौन से डेटा मूल्य हैं।

एक और यह है कि उद्धरण के इन सभी शैलियों में शेल में एक एकल "शब्द" बनाया जाता है, जब तक कि डबल उद्धरण के अंदर $@एक सरणी विस्तार ${x[@]}का उपयोग नहीं किया जाता है। दोनों एकल-उद्धरण रूप हमेशा एक शब्द होते हैं और कभी भी आगे नहीं बढ़ते हैं।


$"..."ksh93 से भी है, 2.0 में बैश में जोड़ा गया।
स्टीफन चेज़लस

\cXमें नहीं है zsh। यह \CXया \C-Xवहाँ ( \cपहले से ही एक विशेष अर्थ है echo)
स्टीफन चेज़ेलस

'let x="'$PATH\"के zshरूप $PATHमें उद्धृत नहीं किया गया है के अलावा अन्य गोले में सूची संदर्भ में गलत है (इसलिए विभाजित + ग्लोब के अधीन होगा जो आपके पास नहीं होगा)।
स्टीफन चेज़लस

आप स्पष्ट करना चाहते हैं कि आप कोर्न जैसे गोले की बात कर रहे हैं, उद्धरण प्रसंस्करण csh, rc, मछली में अलग है ...
स्टीफन चेज़लस

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.