यदि चर नाम को स्ट्रिंग के रूप में संग्रहीत किया जाता है, तो चर मूल्य कैसे प्राप्त करें?


142

यदि मेरे पास स्ट्रिंग के रूप में चर नाम है, तो मैं एक बैश वेरिएबल मान कैसे प्राप्त कर सकता हूं?

var1="this is the real value"
a="var1"
Do something to get value of var1 just using variable a.

प्रसंग:

मेरे पास कुछ एएमआई ( अमेज़ॅन मशीन इमेज ) हैं और मैं प्रत्येक एएमआई के कुछ उदाहरणों को आग देना चाहता हूं। जैसे ही वे बूट करना समाप्त करते हैं, मैं प्रत्येक उदाहरण को उसके एएमआई प्रकार के अनुसार सेटअप करना चाहता हूं। मैं किसी भी एएमआई के अंदर बहुत सारी स्क्रिप्ट या गुप्त कुंजी को सेंकना नहीं चाहता हूं इसलिए मैंने एक सामान्यीकृत स्टार्टअप स्क्रिप्ट तैयार की और मैंने इसे सार्वजनिक रूप से सुलभ लिंक के साथ S3 पर रखा । आर.लोकल में मैंने कोड का छोटा टुकड़ा डाला जो स्टार्टअप स्क्रिप्ट को लाती है और उसे निष्पादित करती है। यह सब मेरे पास एएमआई में है। फिर प्रत्येक एएमआई एक सामान्य कॉन्फ़िगरेशन स्क्रिप्ट का उपयोग करता है जो सभी एएमआई और प्रत्येक के लिए विशेष सेटअप स्क्रिप्ट पर लागू होता है। ये स्क्रिप्ट निजी हैं और इन्हें एक्सेस करने के लिए एक हस्ताक्षरित URL की आवश्यकता होती है।

इसलिए अब, जब मैं एक एएमआई (my_pStreet_ami_1) की एक आग लगाता हूं, तो मैं S3 पर प्रस्तुत एक और फ़ाइल के लिए एक हस्ताक्षरित URL पास करता हूं जिसमें कुंजी / मूल्य जोड़ी के संदर्भ में सभी निजी लिपियों के लिए हस्ताक्षरित URL होता है।

config_url="http://s3.amazo.../config?signature"
my_private_ami_1="http://s3.amazo.../ami_1?signature"
...
जब स्टार्टअप स्क्रिप्ट चलती है, तो यह उपरोक्त फ़ाइल को डाउनलोड करता है और इसे डाउनलोड करता sourceहै। फिर यह अपने एएमआई प्रकार की जांच करता है और अपने लिए सही सेटअप स्क्रिप्ट चुनता है।

ami\_type=GET AMI TYPE #ex: sets ami\_type to my\_private\_ami\_1
setup\_url=GET THE SETUP FILE URL BASED ON AMI\_TYPE # this is where this problem arises

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

जवाबों:


257

आप उपयोग कर सकते हैं ${!a}:

var1="this is the real value"
a="var1"
echo "${!a}" # outputs 'this is the real value'

यह अप्रत्यक्ष पैरामीटर विस्तार का एक उदाहरण है :

पैरामीटर विस्तार का मूल रूप है ${parameter}। का मूल्य parameterप्रतिस्थापित किया जाता है।

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


4
यह OSX बैश में मेरे लिए काम करता है, लेकिन डेबियन नहीं? डेबियन पर मुझे Bad substitutionत्रुटि मिलती है।
23inhouse

11
@ 23inhouse क्या आप अपनी स्क्रिप्ट का उपयोग करके चल रहे हैं /bin/sh? यदि हां, तो /bin/bashइसके बजाय प्रयोग करके देखें । डेबियन निचोड़ के बाद से, इसके बजाय/bin/sh एक सिम्लिंक के रूपdashbash में बदल दिया गया था । dashइस विशेष सिंटैक्स का समर्थन नहीं करता है और एक Bad substitutionत्रुटि आउटपुट करेगा ।
फिल रॉस

8
क्या एक चर नाम के लिए यह काम करने का एक तरीका है जो एक सरणी से संबंधित है?
लूपैक्स

बर्बश पर बैश के साथ काम करता है
सर्गेई पी। उर्फ ​​अज्योर

1
@ डोरोनशाई यह अप्रत्यक्ष पैरामीटर विस्तार का एक उदाहरण है, जिसे gnu.org/software/bash/manual/html_node/…
फिल रॉस

29
X=foo
Y=X
eval "Z=\$$Y"

Z को "foo" पर सेट करता है

ध्यान रखना का उपयोग कर evalके बाद से इस में मूल्यों के माध्यम से कोड की दुर्घटना excution अनुमति दे सकता है ${Y}। इससे कोड इंजेक्शन के माध्यम से नुकसान हो सकता है।

उदाहरण के लिए

Y="\`touch /tmp/eval-is-evil\`"

पैदा करेगा /tmp/eval-is-evil। यह भी कुछ हो सकता है rm -rf /, ज़ाहिर है।



9

मेरे खोज खोजशब्दों को संशोधित किया और इसे पा लिया :)।

eval a=\$$a
आपके समय के लिए धन्यवाद।


इसके इस्तेमाल से ध्यान हटाएं क्योंकि इससे मूल्यों में परिवर्तन के माध्यम से कोड के आकस्मिक प्रवाह की अनुमति मिल सकती है ${Y}। उपयोगकर्ता "एनॉन" के उत्तर में मेरा जोड़ देखें।
कोशिश-पकड़-आखिरकार

यह केवल काम करने वाला उत्तर है। विडंबना है कि यह आपका अपना है!
Ctrl S

8

मेरे साथी zsh उपयोगकर्ताओं के लिए, स्वीकृत उत्तर के रूप में एक ही चीज़ को पूरा करने का तरीका है:

${(P)a}

इसे पैरामीटर नाम प्रतिस्थापन कहा जाता है

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

यदि एक नेस्टेड पैरामीटर या कमांड प्रतिस्थापन के साथ उपयोग किया जाता है, तो उसी के परिणाम को उसी तरह एक पैरामीटर नाम के रूप में लिया जाएगा। उदाहरण के लिए, यदि आपके पास 'फू = बार' और 'बार = बाज' है, तो तार $ {(पी) फू}, $ {(पी) $ {फू}}, और $ {(पी) $ (इको बार) } का विस्तार 'बाज' तक किया जाएगा।

इसी तरह, यदि संदर्भ स्वयं नेस्टेड है, तो ध्वज के साथ अभिव्यक्ति को ऐसे माना जाता है मानो इसे सीधे पैरामीटर नाम से बदल दिया गया हो। यदि यह नेस्टेड प्रतिस्थापन एक से अधिक शब्दों के साथ एक सरणी पैदा करता है तो यह एक त्रुटि है। उदाहरण के लिए, यदि 'name = assoc' जहां पैरामीटर एसोचेटिव एक एसोसिएटिव ऐरे है, तो '$ {$ {(P) नाम} [elt]}' एसोसिएटेड सबस्क्रिप्ट किए गए 'elt' के तत्व को संदर्भित करता है।


0

आधुनिक गोले पहले से ही सरणियों (और यहां तक ​​कि साहचर्य सरणियों) का समर्थन करते हैं। तो कृपया इनका उपयोग करें, और इनका कम उपयोग करें।

var1="this is the real value"
array=("$var1")
# or array[0]="$var1"

फिर जब आप इसे कॉल करना चाहते हैं, तो $ {array [0]} इको करें


अगर मैं कमांडलाइन तर्क से स्ट्रिंग प्राप्त करता हूं (जैसे कि $1)?
जेना

0

उत्तर के आधार पर: https://unix.stackexchange.com/a/111627

###############################################################################
# Summary: Returns the value of a variable given it's name as a string.
# Required Positional Argument: 
#   variable_name - The name of the variable to return the value of
# Returns: The value if variable exists; otherwise, empty string ("").
###############################################################################
get_value_of()
{
    variable_name=$1
    variable_value=""
    if set | grep -q "^$variable_name="; then
        eval variable_value="\$$variable_name"
    fi
    echo "$variable_value"
}

test=123
get_value_of test
# 123
test="\$(echo \"something nasty\")"
get_value_of test
# $(echo "something nasty")

0

सरणियों के साथ एक ही मुद्दा था, यहाँ है कि यदि आप सरणियों में भी हेरफेर कर रहे हैं तो यह कैसे करें:

array_name="ARRAY_NAME"
ARRAY_NAME=("Val0" "Val1" "Val2")

ARRAY=$array_name[@]
echo "ARRAY=${ARRAY}"
ARRAY=("${!ARRAY}")
echo "ARRAY=${ARRAY[@]}"
echo "ARRAY[0]=${ARRAY[0]}"
echo "ARRAY[1]=${ARRAY[1]}"
echo "ARRAY[2]=${ARRAY[2]}"

यह आउटपुट होगा:

ARRAY=ARRAY_NAME[@]
ARRAY=Val0 Val1 Val2
ARRAY[0]=Val0
ARRAY[1]=Val1
ARRAY[2]=Val2
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.