बैकटिक को समझना (`)


35

मैं कमांड का प्रयास कर रहा हूं

$ b=5; echo `$b`;
-bash: 5: command not found

लेकिन यह 5 प्रिंट नहीं करता है क्योंकि यह माना जाता है। मुझे यहां क्या समझ नहीं आ रहा है?

आदेशों में `(backquote / backtick) का क्या अर्थ है? ऐसा लगता है कि `आदेश का मूल्यांकन करता है और उन्हें आउटपुट से बदल देता है।


8
ध्यान दें कि बैकटिक्स की अनुशंसा नहीं की जाती है क्योंकि आप नेस्टेड एग्जीक्यूटिव करने की क्षमता खो देंगे। इनसेट, $ (somecommand) को प्राथमिकता दी जाती है। Imho यह पठनीयता में सुधार करता है।
टॉमी

6
@ टॉमी, नहीं, बैकटिक्स को नेस्टेड किया जा सकता है, लेकिन यह एक दुःस्वप्न बन जाता है, खासकर जब डबल-कोटेशन भी।
स्टीफन चेजलस

जवाबों:


52

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

जैसा कि आप देख सकते हैं, चूंकि $b5 में शामिल है, जब बैकटिक्स bashका उपयोग कमांड चलाने की कोशिश कर रहा है 5और चूंकि ऐसी कोई कमांड नहीं है, तो यह त्रुटि संदेश के साथ विफल हो जाता है।

यह समझने के लिए कि बैकटिक्स कैसे काम करता है, इसे चलाने का प्रयास करें:

$ A=`cat /etc/passwd | head -n1`
$ echo "$A"

cat /etc/passwd |head -n1/etc/passwdफ़ाइल की पहली पंक्ति को प्रिंट करना चाहिए । लेकिन जब से हम backticks का उपयोग करते हैं, यह कंसोल पर प्रिंट नहीं करता है। इसके बजाय यह Aचर में संग्रहीत किया जाता है । आप इसे प्रतिध्वनित कर सकते हैं $A। ध्यान दें कि पहली पंक्ति को प्रिंट करने का अधिक कुशल तरीका कमांड का उपयोग कर head -n1 /etc/passwdरहा है, लेकिन मैं यह बताना चाहता था कि बैकटिक्स के अंदर की अभिव्यक्ति सरल नहीं है।

इसलिए यदि / etc / passwd की पहली लाइन है root:x:0:0:root:/root:/bin/bash, तो पहले कमांड को bash द्वारा डायनामिक रूप से प्रतिस्थापित किया जाएगा A="root:x:0:0:root:/root:/bin/bash"

ध्यान दें कि यह सिंटेक्स बॉर्न शेल का है। उद्धृत करना और भागना जल्दी से एक बुरा सपना बन जाता है विशेष रूप से जब आप उन्हें घोंसले के शिकार शुरू करते हैं। Ksh ने $(...)विकल्प पेश किया जो अब मानकीकृत ( POSIX ) है और सभी गोले (यहां तक ​​कि यूनिक्स 9 से बॉर्न शेल) द्वारा समर्थित है। इसलिए आपको $(...)आजकल के बजाय का उपयोग करना चाहिए जब तक कि आपको बहुत पुराने बॉर्न शेल के लिए पोर्टेबल होने की आवश्यकता न हो।

यह भी ध्यान रखें कि के उत्पादन `...`और $(...)शब्द बंटवारे और बस (केवल zsh में, शब्द बंटवारे) चर विस्तार की तरह फ़ाइल नाम पीढ़ी के अधीन हैं, तो आम तौर पर सूची संदर्भों में उद्धृत किया जाना आवश्यक होगा।


1
हाय @ krzysztof, यह मददगार है! "चूंकि $ b में 5 शामिल हैं, बैश कमांड 5 को चलाने की कोशिश कर रहा है" ठीक वही है जो मैं देख रहा था
Coolcric

you can use quotation marks, like echo "$b"=> क्या "" कुछ खास करता है? ऐसा लगता है echo $bकि यह भी काम करेगा।
टुत्सी रोल्स

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

अच्छा (POSIX)होगा यदि वास्तविक मानक के लिए एक कड़ी होगी।
एरिकबवर्क

1
@ erikb85: यह नोट मेरे द्वारा नहीं जोड़ा गया था, लेकिन मैंने इसे लिंक के साथ संपादित किया है जैसा कि आपने सुझाव दिया :)
Krzysztof Adamski

11

बैकटिक जैसा कहता है वैसा ही करता है। आपने एक पूर्णांक में एक चर सेट किया है। जब आप उस वैरिएबल को बैकटिक्स के अंदर रखते हैं, तो bash इसे कमांड के रूप में निष्पादित करने का प्रयास करेगा। चूंकि यह एक कमांड नहीं है, इसलिए आपको वह त्रुटि दिखाई देती है जो आपने देखी थी।

आप क्या करना चाहते हैं बस:

$ b=5; echo $b

बेहतर समझने के लिए, इसके साथ तुलना करें:

$ b=5; a=`echo $b`; echo $a
  5

8

अपनी लाइन को चरण दर चरण आगे बढ़ाते हुए इसे समझाना चाहिए।

$ b=5; echo `$b`;
  1. चर सेट करता है b5 पर
  2. मूल्यांकन करता है $b (प्रभावी रूप से चलता है 5)
  3. echoऊपर मूल्यांकन के आउटपुट से बचें।

तो हां, आपको जो आउटपुट मिला है, वह अपेक्षित है। आप एक चर की सामग्री का मूल्यांकन कर रहे हैं, न कि वास्तविक कमांड जिसे आपने सोचा था कि आप थे। सब कुछ आप backticks के अंदर डाल दिया है एक नए (उप) खोल में simplay मूल्यांकन (संचालित) है।


हाय @gertvdijk, आपकी पोस्ट के लिए धन्यवाद! मैं सोच रहा था कि `अपनी सामग्री का मूल्यांकन करने के बाद जो कुछ बचा है, उसे वापस कर दिया जाए। तो, मैंने सोचा कि $ $ 'इसे वापस मुद्रित करने के लिए प्रतिध्वनि के लिए 5 लौट आए होंगे
कूलक्रीक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.