शेल प्रोग्रामिंग में $ (कमांड) और `कमांड 'के बीच क्या अंतर है?


258

Sh / ksh / bash में एक चर के रूप में एक कमांड के आउटपुट को स्टोर करने के लिए, आप या तो कर सकते हैं

var=$(command)

या

var=`command`

यदि दोनों विधियों के बीच कोई अंतर है तो क्या होगा?



आपको जीट कोडिंग गाइडलाइन में विस्तृत नेस्टेड मुद्दा मिलेगा: नीचे मेरा जवाब देखें
VonC

जवाबों:


274

बैकटिक्स / कब्र को $()कमांड प्रतिस्थापन के पक्ष में चित्रित किया गया है क्योंकि $()आसानी से अपने भीतर घोंसला बना सकते हैं $(echo foo$(echo bar))। अन्य अंतर हैं जैसे कि बैकस्लैक्स को बैकटीक / ग्रेवमार्क संस्करण में कैसे पार्स किया जाता है, आदि।

हमेशा $ (...) सिंटैक्स पसंद करने के लिए कई कारणों से BashFAQ / 082 देखें ।

विभिन्न अंतरों की विस्तृत जानकारी के लिए POSIX कल्पना भी देखें ।


25
अच्छा लिंक, लेकिन उस पाठ नहीं है बहिष्कार के पक्ष में backquotes $(...)- यह सिर्फ विकल्प के रूप में उन्हें नोटों।
नॉर्मन ग्रे

24
@ नोर्मनग्रे पॉसिक ने पदावनत शब्द नहीं कहा हो सकता है, लेकिन यह कहना है कि "the backquoted variety of command substitution is not recommended"जो कि आईएमएचओ को अपदस्थ कहने का एक लंबा घुमावदार तरीका है
SiegeX

11
POSIX ने बैकटिक्स को चित्रित नहीं किया, बल्कि $(...)एक वैकल्पिक विधि के रूप में जोड़ा गया । बैकटिक्स के साथ कोई ज्ञात कार्यान्वयन बग नहीं है, लेकिन कई ज्ञात कार्यान्वयन बग हैं $(...) । तो पोर्टेबिलिटी मुद्दों के लिए गैर-नेस्टेड कॉल के लिए बैकटिक्स का उपयोग करने की सिफारिश की जाती है। $(...)एक पुनरावर्ती पार्सर की जरूरत है, लेकिन यह ksh86 के साथ उपयोग नहीं किया गया था जिसने सुविधा पेश की। सही कार्यान्वयन की सूची के लिए inulm.de/~mascheck/various/cmd-subst पर चेक करें । एक अनुरूप शेल को D.2 को छोड़कर सभी मामलों का समर्थन करने की आवश्यकता होती है।
स्किल

2
POSIX में अन्य चीजें हैं जिन्हें देखने की जरूरत है deprecated, जैसे कि इसका उपयोग waitpid()आपको exit()पैरामीटर से पूर्ण 32 बिट्स को देखने से रोकता है , लेकिन हाल के बॉर्न शेल को छोड़कर सभी गोले अब भी कॉल के waitpid()बजाय उपयोग करते waitid()हैं जो अब उपलब्ध है 26 साल।
स्किल

उत्तर में लिंक संकेत देता है कि बैकटिक्स और $(), के बीच कुछ अंतर हैं , जो प्रलेखन के इस भाग में अधिक स्पष्ट है । मतभेद केवल घोंसले के शिकार के बारे में नहीं है।
कुछ प्रोग्रामर

39

वे ऐसा ही व्यवहार करते हैं। अंतर वाक्यात्मक है: इससे घोंसला बनाना आसान $()है ``:

listing=$(ls -l $(cat filenames.txt))

बनाम

listing=`ls -l \`cat filenames.txt\``

10
echo $(echo \$abc)समान नहीं है echo `echo \$abc`‍- अंतर भी मौजूद हैं $(echo \`)और $(echo \\)
पीटर।

एक और अंतर है: echo foo `#comment`बनाम echo foo $(#comment)। दूसरा काम नहीं करता है। (मल्टी-लाइन कमांड में टिप्पणी करने के लिए उपयोग किया जाता है।)
बुद्धिमानीबुल

27

जुलाई 2014: प्रतिबद्ध f25f5e6 ( एलिया पिंटोdevzero2000 द्वारा ) , अप्रैल 2014, Git 2.0) नेस्टिंग मुद्दे में जोड़ता है:

Backquoted प्रपत्र कमांड प्रतिस्थापन के लिए पारंपरिक विधि है, और POSIX द्वारा समर्थित है।
हालांकि, सभी लेकिन सरलतम उपयोग जल्दी जटिल हो जाते हैं।
विशेष रूप से, एम्बेडेड कमांड प्रतिस्थापन और / या दोहरे उद्धरण चिह्नों का उपयोग बैकस्लैश चरित्र के साथ सावधानीपूर्वक भागने की आवश्यकता होती है

इसीलिए git / Documentation / CodingGuidelines का उल्लेख है:

हम $( ... )कमांड प्रतिस्थापन के लिए पसंद करते हैं ; `` के विपरीत, यह ठीक से घोंसला बनाता है
यह होना चाहिए था जिस तरह से बॉर्न ने इसे पहले दिन से ही जादू कर दिया था, लेकिन दुर्भाग्य से ऐसा नहीं है।

थिटन ने टिप्पणी की :

यही कारण है कि `echo `foo`` सामान्य रूप से अंतर्निहित अस्पष्टता के कारण काम नहीं करेगा क्योंकि प्रत्येक ``खुलने या बंद हो सकता है।
यह किस्मत या विशेष सुविधाओं के कारण विशेष मामलों के लिए काम कर सकता है।


अद्यतन जनवरी 2016: Git 2.8 (मार्च 2016) से पूरी तरह से बैकटिक्स से छुटकारा मिल जाता है।

देखें प्रतिबद्ध ec1b763 , 9c10377 प्रतिबद्ध , c7b793a प्रतिबद्ध , 80a6b3f प्रतिबद्ध , 9375dcf प्रतिबद्ध , e74ef60 प्रतिबद्ध , 27fe43e प्रतिबद्ध , प्रतिबद्ध 2525c51 , becd67f प्रतिबद्ध , a5c98ac प्रतिबद्ध , प्रतिबद्ध 8c311f9 , प्रतिबद्ध 57da049 , 1d9e86f प्रतिबद्ध , प्रतिबद्ध 78ba28d , efa639f प्रतिबद्ध , प्रतिबद्ध 1be2fa0 , प्रतिबद्ध 38e9476 , कमिटमेंट 8823d2f , कमिट 32858a0 , कमिट cd914d8(12 जनवरी 2016) एलिया पिंटो ( devzero2000) द्वारा
(द्वारा विलय Junio सी Hamano - gitster- में e572fef प्रतिबद्ध , 22 जनवरी 2016)

गिट 2.8 से, यह सब है $(...), और नहीं `...`


2
$()POSIX- निर्दिष्ट भी है - एक उद्धरण जो बैकटिक्स को "POSIX- समर्थित" के रूप में वर्णित करता है, इस तरह से इसका मतलब है कि यह उनके लिए अद्वितीय है भ्रामक है। यह केवल (1970 के दशक का) पूर्व-पॉसिक्स बॉर्न है जहां बैकटिक्स एकमात्र समर्थित सिंटैक्स हैं।
चार्ल्स डफी

25

जब पुराने बैक-टिक फॉर्म का उपयोग किया जाता है, तो बैकस्लैश अपने शाब्दिक अर्थ को बनाए रखता है, जब $, `, या \ के बाद। बैकस्लैश से पहले नहीं लगाया गया पहला बैक-टिक कमांड प्रतिस्थापन को समाप्त करता है।

नए $(command)रूप का उपयोग करते समय , कोष्ठक के बीच के सभी अक्षर कमांड बनाते हैं; किसी के साथ भी विशेष व्यवहार नहीं किया जाता है।

दोनों रूपों को नेस्टेड किया जा सकता है, लेकिन बैक-टिक विविधता के लिए निम्न फॉर्म की आवश्यकता होती है।

`echo \`foo\`` 

विरोध के रूप में:

$(echo $(foo))

1
माइनर करेक्शन, बैकटिक वर्जन और वर्जन दोनों $()पोसिक्स कंप्लेंट हैं।
घेराबंदी

5

कमांड के अंदर उपयोग किए जा सकने वाले वर्णों को छोड़कर, कोई अंतर नहीं है। आप अधिक जटिल दो-स्तरीय-गहरी कमांड प्रतिस्थापन के लिए $ (...) वाले (और इसके विपरीत) के अंदर `... ' आदेश भी डाल सकते हैं ।

बैकस्लैश चरित्र / ऑपरेटर की थोड़ी अलग व्याख्या है। अन्य बातों के अलावा, जब घोंसले के शिकार ... ... ' प्रतिस्थापन कमांड, तो आपको \ _ के साथ आंतरिक ` वर्णों से बचना चाहिए , जबकि $ () सबस्टेशन के साथ यह नेस्टिंग को स्वचालित रूप से समझता है।


0

"यदि दोनों विधियों के बीच कोई अंतर है तो क्या होगा?"

इस व्यवहार पर ध्यान दें:

A="A_VARIABLE"
echo "$(echo "\$A")"
echo "`echo "\$A"`"

आपको ये परिणाम मिलेंगे:

$A
A_VARIABLE

 

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