क्या शेल स्क्रिप्ट के साथ एक चर की सामग्री को प्रिंट करना संभव है? (अप्रत्यक्ष संदर्भ)


13

मान लें कि मैंने निम्नलिखित चर घोषित कर दिए हैं:

$ var='$test'
$ test="my string"

यदि मैं उनकी सामग्री को प्रिंट करता हूं तो मुझे निम्नलिखित दिखाई देंगे:

$ echo $var
$test

$ echo $test
my string

मैं उस सामग्री की सामग्री $var(जो सामग्री है $test) को मुद्रित करने का एक तरीका खोजना चाहता हूं । इसलिए मैंने निम्नलिखित करने की कोशिश की:

$ echo $(echo $var)
$test

लेकिन यहां परिणाम है $testऔर नहीं "my string"... क्या बैश का उपयोग करके चर की सामग्री को प्रिंट करना संभव है?


क्या आप अपने पोस्ट को यह कहने के लिए संपादित कर सकते हैं कि आप किस शेल का उपयोग कर रहे हैं, या आपके पास क्या पोर्टेबिलिटी की आवश्यकताएं हैं?
माइकल होमर

@MichaelHomer ज़रूर, लेकिन मैं वास्तव में इस जानकारी की जाँच कैसे कर सकता हूँ?
राफेल म्युनार्स्क

यह कुछ और है जिसे आप जांचने के लिए कुछ चुनते हैं। उदाहरण के लिए, क्या आप अपनी स्क्रिप्ट्स को ash, या bash, cshया dash, ..., या zsh, या POSIX के साथ चला रहे हैं sh, या आपको विभिन्न प्रणालियों में काम करने की आवश्यकता है?
माइकल होमर

@MichaelHomer आह, मैं देखता हूं ... मैं बैश का उपयोग कर रहा हूं। मैं सिर्फ अंतिम प्रश्न बदलूंगा और फिर एक नया टैग डालूंगा।
राफेल म्युनार्स्क

जवाबों:


21

आप इसे बैश के अप्रत्यक्ष चर विस्तार का उपयोग करके पूरा कर सकते हैं (जब तक कि यह $आपके संदर्भ चर से बाहर निकलने के लिए ठीक है ):

$ var=test
$ test="my string"
$ echo "$var"
test
$ echo "${!var}"
my string

3.5.3 शैल पैरामीटर विस्तार


10

उस मामले के लिए जब आपके द्वारा उपयोग किए जा सकने वाले चर नाम varउपसर्ग में $हो eval:

$ var='$test'
$ test="my string"
$ eval echo $var
my string

यहाँ क्या हुआ:

  • bash $varमूल्य का विस्तार करता है $test, एक eval echo $testकमांड का निर्माण करता है ;
  • evalecho $testअभिव्यक्ति का मूल्यांकन करता है और एक वांछित परिणाम पैदा करता है।

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


यकीन है, यह गलत है। मूल पोस्ट में एकल उद्धरण हैं। फिक्स्ड।
दानिला किवर

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

9

Jesse_b के उत्तर के समान , लेकिन चर अप्रत्यक्ष के बजाय नाम संदर्भ चर का उपयोग करना ( bash4.3+ की आवश्यकता है ):

$ declare -n var=test
$ test="my string"
$ echo "$var"
my string

नाम संदर्भ चर varउस चर का नाम है जिसे वह संदर्भित कर रहा है। जब चर को इस रूप में परिभाषित किया जाता है $var, तो दूसरे चर का मान वापस आ जाता है।

bash नाम के संदर्भों को पुनरावर्ती रूप से हल करता है:

$ declare -n var1=var2
$ declare -n var2=test
$ test="hello world"
$ echo "$var1"
hello world

पूर्णता के लिए, एक साहचर्य सरणी का उपयोग करना ( bash4.0+ में) आवश्यकताओं के आधार पर इसे हल करने का एक तरीका भी है:

$ declare -A strings
$ strings[test]="my string"
$ var=test
$ echo "${strings[$var]}"
my string

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


3

के साथ zsh:

$ var='$test'
$ test='*'
$ printf '%s\n' ${(e)var}
*

किसी भी बॉर्न जैसे खोल के साथ

$ eval 'printf "%s\n" "'"$var"'"'
*

याद रखें कि उन गोले में परिवर्तन को विभाजित करने के लिए उद्धृत किया जाना चाहिए + ग्लोब ( zshएक अपवाद होने के नाते) और echoइसका उपयोग मनमाने डेटा के लिए नहीं किया जा सकता है।

चूँकि दोनों के साथ (e)और evalशेल कोड मूल्यांकन है, इसलिए यह महत्वपूर्ण है कि $varआपके नियंत्रण में रहें अन्यथा यह एक मनमाना कमांड इंजेक्शन भेद्यता ( ${!var}दृष्टिकोण के साथ समान ) हो सकता है।

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