2009-11-07 5 views
10

चलो कहते हैं कि मैं एक चर के नाम एक और चर में संग्रहीत करते हैं:लुक खोल चर, परोक्ष रूप से

myvar=123 
varname=myvar 

अब, मैं सिर्फ $ VARNAME चर का उपयोग करके 123 प्राप्त करना चाहते हैं। क्या इसके लिए कोई सीधा तरीका है? मैं ऐसी कोई पार्टी नाम से देखने के लिए builtin पाया है, इसलिए इस के साथ आया था:

function var { v="\$$1"; eval "echo "$v; } 

तो

var $varname # gives 123 

जो अंत में बहुत बुरा नहीं लगता है, लेकिन मैं अगर मैं सोच रहा हूँ कुछ और स्पष्ट याद किया। अग्रिम में धन्यवाद!

+0

इसे 6 साल बाद पूछे गए प्रश्न के डुप्लिकेट के रूप में चिह्नित किया गया है? यह प्रश्न भी IMHO + उत्तर लिंक किए गए लोगों की तुलना में स्पष्ट है। – inger

उत्तर

12

man page of bash से:

${!varname} 

पैरामीटर का पहला वर्ण एक विस्मयादिबोधक बिंदु है, तो चर अविवेक का एक स्तर शुरू की है। बैश चर के नाम के रूप में शेष पैरामीटर से गठित चर के मान का उपयोग करता है; इस चर को तब विस्तारित किया जाता है और उस मान का उपयोग पैरामीटर के मान के बजाय प्रतिस्थापन में किया जाता है। यह अप्रत्यक्ष विस्तार के रूप में जाना जाता है।

+0

बेशक, यह है। आरटीएफएम की कोशिश की, लेकिन किसी भी तरह से यह विवरण: ----------------- $ {! उपसर्ग *} $ {! उपसर्ग @} उपसर्ग मिलान करने वाले नाम। चर के नामों का विस्तार करता है जिनके नाम उपसर्ग के साथ शुरू होते हैं, IFS विशेष चर के पहले वर्ण से अलग होते हैं। जब @ का उपयोग किया जाता है और विस्तार डबल कोट्स के भीतर प्रकट होता है, तो प्रत्येक चर नाम एक अलग शब्द तक फैलता है। ----------------- ने मुझे स्पष्ट उत्तर के रूप में नहीं मारा। उसके लिए चीयर्स! – inger

+0

@DigitalRoss: प्रश्न "बैश" के साथ टैग किया गया था, तो आप उत्तर को पॉज़िक्स मानक तक क्यों सीमित करना चाहते हैं? – tangens

+1

यह एक अच्छा जवाब है, और हाँ यह बैश पर लागू होता है। मुझे लगता है कि सही उत्तर '$ {! Varname} 'की घोषणा करेगा और फिर ओपी को संभावित परेशानी से दूर रखने के लिए पोर्टेबिलिटी समस्या पर ध्यान दें। – DigitalRoss

12

प्रत्यक्ष पॉज़िक्स-अनुरूप वाक्यविन्यास नहीं है, केवल bash ism है।

eval t="\$$varname" 

यह, किसी भी Posix खोल पर काम करेंगे उन प्रणालियों जहां bash लॉगिन खोल और /bin/sh छोटे और ash की तरह तेजी से कुछ है जिनमें शामिल हैं: मैं आमतौर पर यह करते हैं। मुझे बैश पसंद है और इसे मेरे लॉगिन खोल के लिए उपयोग करें, लेकिन मैं कमांड फ़ाइलों में bashisms से बचें।


नोट: बैश-विशिष्ट स्क्रिप्ट लिखने में एक समस्या यह है कि भले ही आप स्थापित होने पर बैश पर भरोसा कर सकें, यह पथ पर कहीं भी हो सकता है। उस मामले में पूरी तरह से सामान्य /usr/bin/envshebang शैली का उपयोग करने के लिए एक अच्छा विचार हो सकता है, लेकिन ध्यान दें कि यह अभी भी 100% पोर्टेबल नहीं है और इसमें सुरक्षा समस्याएं हैं।

+0

उस संदर्भ के आधार पर जिसमें आपको मूल्य की आवश्यकता है, आप असाइनमेंट के बजाय '$ (eval \ $$ varname)' का उपयोग कर सकते हैं। –

+0

लगभग उस पर कोशिश की, लेकिन इसे याद किया। इसके लिए छोटा - उस के लिए चीयर्स! – inger

+0

'$ (....) 'गैर-पॉजिक्स नहीं है? क्या यह '\' eval \ $$ varname' \ 'इसके बजाय नहीं होना चाहिए? –

1

${!varname} चाल

$ var="content" 
$ myvar=var 
$ echo ${!myvar} 
content 
+0

धन्यवाद, ऐसा लगता है कि आपका जवाब टैंगेंस की तुलना में बस एक पल बाद आया, इसलिए मैंने इसे चुना :) – inger

1

मैं आमतौर पर Advance Bash-Scripting Guide को देखो जब मैं अपने बैश कौशल तरोताजा करने की जरूरत है क्या करना चाहिए।

पर Indirect References

संकेतन आपके सवाल का रंग-रूप के बारे में है:

Version < 2 
\$$var 

Version >= 2 
${!varname} 
+0

हम्म, उस गाइड को जल्दी से देखा - स्पष्ट रूप से बहुत जल्दी :) ऐसा लगता है कि मुझे इसे ठीक से पढ़ना है .. टिप के लिए धन्यवाद ! – inger

+0

यह मेरी पसंद का त्वरित संदर्भ है, मैं इसे मैन पेजों की तुलना में अधिक बार उपयोग करता हूं। लेकिन जैसा कि आप कहते हैं, कभी-कभी एक त्वरित नज़र पर्याप्त नहीं होती है। –

+0

सामान्य रूप से, एबीएस को नमक के विशाल अनाज के साथ लिया जाना चाहिए। हालांकि, इस उत्तर के साथ कुछ भी गलत नहीं है। – tripleee

0
# bmuSetIndirectVar() 
# TO DOUBLE CHECK THIS COMMENT AND DEMO 
# This function is an helper to read indirect variables. 
# i.e. get the content of a variable whose name is saved 
# within an other variable. Like: 
# MYDIR="/tmp" 
# WHICHDIR="MYDIR" 
#  bmuSetIndirectVar "WHICHDIR" "$MYDIR" 
# 
bmuSetIndirectVar(){ 
    tmpVarName=$1 
    locVarName=$1 
    extVarName=$2 
    #echo "debug Ind Input >$1< >$2<" 
    eval tmpVarName=\$$extVarName 
    #echo "debug Ind Output >$tmpVarName< >$extVarName<" 
    export $locVarName="${tmpVarName}" 
} 

मैं वर्तमान में इस छोटे से समारोह का उपयोग कर रहा हूँ। मैं इसके साथ पूरी तरह से खुश नहीं हूं, और मैंने वेब पर विभिन्न समाधान देखे हैं (अगर मुझे याद होगा कि मैं उन्हें यहां लिखूंगा), लेकिन ऐसा लगता है कि यह काम करता है। इन कुछ पंक्तियों में पहले से ही कुछ अनावश्यकता और अतिरिक्त डेटा है लेकिन यह डिबगिंग के लिए सहायक था।

आप जगह, यानी में यह देखने के लिए जहां मैं इसे उपयोग कर रहा हूँ चाहते हैं, की जाँच करें: https://github.com/mariotti/bmu/blob/master/bin/backmeup.shellfunctions.sh

बेशक

यह सबसे अच्छा समाधान नहीं है, लेकिन मुझे काम के साथ चल रहा है, आशा में बनाया मैं इसे जल्द से जल्द कुछ और सामान्य के साथ बदल सकता हूं।

+0

प्रश्नों से पहले;) मुझे इस फ़ंक्शन की पसंद नहीं है कि मैं एक "eval" का उपयोग करता हूं जो आमतौर पर खराब डिज़ाइन के लिए एक ट्रिगर होता है। बेशक ऐसे स्थान हैं जहां आपको इसकी आवश्यकता है। मुझे क्या पसंद है कि एक फ़ंक्शन का उपयोग करके मैं समस्या से कोड को अलग कर सकता हूं और इसे बाद में अनुकूलित कर सकता हूं। हो सकता है कि एक शैल संस्करण चेक या इसी तरह का परिचय दें। – mariotti