साथ काम करने का एक अच्छा तरीका 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
करने के लिए एक विकल्प जोड़ा गया है , लेकिन वह नहीं है जो हम चाहते हैं कि या तो हमारे रूप में एक वैश्विक संस्करण सेट हो जाए क्योंकि कॉलर एक फ़ंक्शन के विपरीत था, जैसे:declare
setvar
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="';:(){ :|:&};:'"
)