बैश वैरिएबल एक्सपेंशन कोट्स को बरकरार क्यों रखता है?


12
> echo "hi"
hi
> VAR='echo "hi"'
> $VAR
"hi"

उपरोक्त कमांड का आउटपुट अलग क्यों है?

एक समान बात एकल उद्धरण के साथ होती है:

> VAR="echo 'hi'"
> $VAR
> 'hi'

6
कृपया निष्पादन योग्य स्क्रिप्ट स्निपेट्स को चर में एम्बेड करने की आदत न डालें। यह सबसे अच्छी तरह से मुश्किल हो जाता है और evalसंभावित सुरक्षा छिद्रों की खान है जो आपको बहुत सावधानी से चलना चाहिए
jw013

@ jw013 अच्छी बात और शानदार लेख। मुझे यह पसंद है "वेरिएबल्स डेटा होल्ड करें, फ़ंक्शंस कोड पकड़ें।" पहले लिंक से, लेकिन मेरे उपयोग के लिए, एक फ़ंक्शन (इस मामले में at) को दिया गया डेटा कोड है। कोड को व्यवस्थित / एकत्र करने के लिए सुरक्षित तरीके से कोई सुझाव जो दिया जाएगा at?
कोरी क्लेन

atshइनपुट के रूप में वाक्यविन्यास लेता है । इस प्रकार इनपुट का atअर्थ है कि जनरेट करने के लिए इनपुट , उचित रूप से उद्धृत shमनमाना इनपुट से वाक्यविन्यास, जो कि तुच्छ नहीं है, इसलिए यदि संभव हो तो मैं इसे टालने की कोशिश करूंगा। यदि आप पूरा करने के लिए कोशिश कर रहे हैं तो यह थोड़ा और विस्तार दे सकता है।
jw013

क्षमा करें, मैं बहुत अधिक विवरण के साथ विचलित नहीं करना चाहता था, लेकिन मैं जो कर रहा हूं वह वास्तव में जटिल नहीं है, आईएमओ। मैं एक ऐसी स्क्रिप्ट बना रहा हूं, जो "समय" और "संदेश" लेती है। यह तब atदिए गए "समय" के लिए चलता है , और atकमांड चलाने के लिए कहता है dzen2dzen2स्टड से "संदेश" लेता है, और कुछ अन्य स्थिर मापदंडों का भी उपयोग करता है। कठिनाई यह है कि मुझे उपयोगकर्ता से "संदेश" पैरामीटर को dzen2कमांड में पाइप करने की आवश्यकता है , लेकिन मैं वास्तव में dzen2खुद को नहीं चला रहा हूं, मैं atइसे करने के लिए कह रहा हूं ।
कोरी क्लेन

जवाबों:


16

अतिरिक्त मूल्यांकन कदम से ही उद्धरणों की अतिरिक्त जोड़ी का सेवन किया जाएगा। उदाहरण के लिए मजबूर eval:

bash-4.2$ VAR='echo "hi"'

bash-4.2$ $VAR
"hi"

bash-4.2$ eval $VAR
hi

लेकिन आम तौर पर एक स्ट्रिंग में मापदंडों के साथ कमांड डालने के लिए एक बुरा विचार है। इसके बजाय एक सरणी का उपयोग करें:

bash-4.2$ VAR=(echo "hi")

bash-4.2$ "${VAR[@]}"
hi

1
यह भी ध्यान रखना महत्वपूर्ण है कि उद्धरणों का मूल्यांकन अलग तरीके से किया जाता है; दोहरे उद्धरण (") संलग्न स्ट्रिंग के मूल्यांकन की अनुमति देते हैं, एकल उद्धरण (') स्ट्रिंग को शाब्दिक के रूप में प्रिंट करते हैं। उदाहरण: "$(ls)"और '$(ls)'। यही कारण है कि उद्धरण मूल प्रश्न उदाहरणों में दिखाई देते हैं।
जोसेफ केर्न

एक सरणी भी समस्याओं का एक स्रोत है। कोड फ़ंक्शंस का है, डेटा वेरिएबल्स का। आपके द्वारा प्रस्तुत उदाहरण केवल इसलिए काम करता है क्योंकि उद्धरण सरणी के विभाजन में हटा दिए जाते हैं। ए printf '<%s> ' "${VAR[@]}"दिखाएगा कि उद्धरण पहले ही हटा दिए गए हैं। यदि आप VAR VAR=(echo \"hi\")को वास्तव में उद्धरण के रूप में सेट करते हैं, तो वही समस्या फिर से दिखाई देती है, $ ${VAR[@]}प्रिंट होगी"hi"

9

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


2

यदि आप थोड़ा पीछे हटते हैं, तो आप देख सकते हैं कि चर प्रतिस्थापन बिल्कुल उद्धरण क्यों बनाए रखना चाहिए।

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

यदि एक प्रोग्रामर कुछ वैरिएबल के मान के साथ एक स्ट्रिंग चाहता है, जो इंटरपोल किया गया हो:

VAR=two
STRING="one $VAR three"

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

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