साथ काम करने का एक अच्छा तरीका evalयह है कि इसे echoपरीक्षण के लिए बदल दिया जाए । echoऔर evalउसी तरह काम करें (यदि हम \xकुछ echoकार्यान्वयनों द्वारा किए गए विस्तार bashको कुछ शर्तों के तहत अलग कर दें)।
दोनों आदेशों के बीच में एक स्थान के साथ उनके तर्क शामिल होते हैं। अंतर यह है कि है echo को प्रदर्शित करता है परिणाम, जबकि eval मूल्यांकन करता है / व्याख्या खोल कोड के रूप में परिणाम।
तो, देखना है कि शेल कोड क्या है
eval $(echo $var_name=$var_value)
मूल्यांकन करेंगे, आप चला सकते हैं:
$ echo $(echo $var_name=$var_value)
fruit=blue orange
यह वह नहीं है जो आप चाहते हैं, जो आप चाहते हैं:
fruit=$var_value
इसके अलावा, $(echo ...)यहाँ उपयोग करने का कोई मतलब नहीं है।
उपरोक्त उत्पादन करने के लिए, आप दौड़ेंगे:
$ echo "$var_name=\$var_value"
fruit=$var_value
तो, इसकी व्याख्या करने के लिए, यह बस है:
eval "$var_name=\$var_value"
ध्यान दें कि इसका उपयोग व्यक्तिगत सरणी तत्वों को सेट करने के लिए भी किया जा सकता है:
var_name='myarray[23]'
var_value='something'
eval "$var_name=\$var_value"
जैसा कि दूसरों ने कहा है, यदि आपको अपने कोड के bashविशिष्ट होने की परवाह नहीं है , तो आप निम्न का उपयोग कर सकते हैं declare:
declare "$var_name=$var_value"
हालाँकि ध्यान दें कि इसके कुछ दुष्प्रभाव हैं।
यह चर के दायरे को उस फ़ंक्शन तक सीमित करता है जहां यह चलाया जाता है। इसलिए आप इसका उपयोग चीजों में उदाहरण के लिए नहीं कर सकते हैं:
setvar() {
var_name=$1 var_value=$2
declare "$var_name=$var_value"
}
setvar foo bar
क्योंकि यह घोषित करने के लिए एक fooचर स्थानीय setvarबेकार होगा।
bash-4.2एक वैश्विक चर घोषित -gकरने के लिए एक विकल्प जोड़ा गया है , लेकिन वह नहीं है जो हम चाहते हैं कि या तो हमारे रूप में एक वैश्विक संस्करण सेट हो जाए क्योंकि कॉलर एक फ़ंक्शन के विपरीत था, जैसे:declaresetvar
setvar() {
var_name=$1 var_value=$2
declare -g "$var_name=$var_value"
}
foo() {
local myvar
setvar myvar 'some value'
echo "1: $myvar"
}
foo
echo "2: $myvar"
जो उत्पादन होगा:
1:
2: some value
यह भी ध्यान दें कि जब declareकहा जाता है declare(वास्तव bashमें कोर्न शेल के typesetबिलिन से अवधारणा को उधार लिया गया है ), यदि चर पहले से ही सेट है, declareतो एक नया चर घोषित नहीं करता है और जिस तरह से असाइनमेंट किया जाता है वह चर के प्रकार पर निर्भर करता है।
उदाहरण के लिए:
varname=foo
varvalue='([PATH=1000]=something)'
declare "$varname=$varvalue"
यदि varnameएक स्केलर , सरणी या साहचर्य सरणी के रूप में घोषित किया गया था, तो एक अलग परिणाम (और संभावित रूप से बुरा दुष्प्रभाव होगा) का उत्पादन करेगा ।
evalउस तरीके का इस्तेमाल करना गलत है। आप$var_valueइसे पास करने से पहले विस्तार कर रहे हैंevalजिसका अर्थ है कि इसे शेल कोड के रूप में व्याख्या किया जाएगा! (उदाहरण के लिए प्रयास करेंvar_value="';:(){ :|:&};:'")