जैसा कि मैं आपका अर्थ लेता हूं, मुझे विश्वास नहीं है कि इनमें से कोई भी उत्तर सही है। eval
किसी भी तरह से आवश्यक नहीं है, और न ही आपको अपने चर का दो बार मूल्यांकन करने की कोई आवश्यकता है।
यह सच है, @Gilles बहुत करीब आता है, लेकिन वह संभवतः ओवरराइडिंग मानों की समस्या को संबोधित नहीं करता है और यदि आपको उन्हें एक से अधिक बार आवश्यकता होती है तो उनका उपयोग कैसे किया जाना चाहिए। आखिरकार, एक टेम्पलेट का उपयोग एक से अधिक बार किया जाना चाहिए, है ना?
मुझे लगता है कि यह अधिक क्रम है जिसमें आप उनका मूल्यांकन करते हैं जो महत्वपूर्ण है। निम्नलिखित को धयान मे रखते हुए:
ऊपर
यहां आप कुछ डिफॉल्ट सेट करेंगे और उन्हें कॉल करने के लिए प्रिंट करने की तैयारी करेंगे ...
#!/bin/sh
_top_of_script_pr() (
IFS="$nl" ; set -f #only split at newlines and don't expand paths
printf %s\\n ${strings}
) 3<<-TEMPLATES
${nl=
}
${PLACE:="your mother's house"}
${EVENT:="the unspeakable."}
${ACTION:="heroin"}
${RESULT:="succeed."}
${strings:="
I went to ${PLACE} and saw ${EVENT}
If you do ${ACTION} you will ${RESULT}
"}
#END
TEMPLATES
मध्य
यह वह जगह है जहाँ आप अपने परिणामों के आधार पर अपने प्रिंट फ़ंक्शन पर कॉल करने के लिए अन्य कार्यों को परिभाषित करते हैं ...
EVENT="Disney on Ice."
_more_important_function() { #...some logic...
[ $((1+one)) -ne 2 ] && ACTION="remedial mathematics"
_top_of_script_pr
}
_less_important_function() { #...more logic...
one=2
: "${ACTION:="calligraphy"}"
_top_of_script_pr
}
तल
अब आपको यह सब सेटअप मिल गया है, इसलिए यहां आप अपने परिणामों को निष्पादित और खींच लेंगे।
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
परिणाम
मैं एक पल में क्यों अंदर जाऊंगा, लेकिन ऊपर चलने से निम्नलिखित परिणाम मिलते हैं:
_less_important_function()'s
प्रथम रन:
मैं आपकी माँ के घर गया और बर्फ पर डिज्नी को देखा ।
यदि आप सुलेख करते हैं तो आप सफल होंगे।
फिर _more_important_function():
मैं कब्रिस्तान गया और बर्फ पर डिज्नी को देखा।
यदि आप सुधारात्मक गणित करेंगे तो आप सफल होंगे।
_less_important_function()
फिर:
मैं कब्रिस्तान गया और बर्फ पर डिज्नी को देखा।
यदि आप उपचारात्मक गणित करते हैं तो आपको इसका पछतावा होगा।
यह काम किस प्रकार करता है:
यहाँ की प्रमुख विशेषता यह है कि conditional ${parameter} expansion.
आप किसी वैरिएबल को किसी मान पर सेट कर सकते हैं, यदि यह प्रपत्र का उपयोग करने के लिए परेशान या अशक्त हो:
${var_name
: =desired_value}
यदि इसके बजाय आप केवल एक अस्थिर चर सेट करना चाहते हैं, तो आप छोड़ देंगे :colon
और अशक्त मान जैसा है वैसा ही रहेगा।
SCOPE पर:
आप देख सकते हैं कि उपरोक्त उदाहरण में $PLACE
और $RESULT
जब पहले से ही कॉल किया गया हो तब parameter expansion
भी बदल _top_of_script_pr()
जाता है, संभवत: इसे चलाने पर उन्हें सेट किया जा सकता है। इसका कारण यह है कि _top_of_script_pr()
यह एक ( subshelled )
फ़ंक्शन है - मैंने इसे दूसरों के लिए उपयोग किए जाने के parens
बजाय संलग्न { curly braces }
किया। क्योंकि इसे एक उप-संस्करण में कहा जाता है, प्रत्येक चर जो इसे सेट करता है locally scoped
और जैसे ही यह अपने मूल शेल में लौटता है, वे मान गायब हो जाते हैं।
लेकिन जब _more_important_function()
सेट $ACTION
होता है globally scoped
तो यह _less_important_function()'s
दूसरे मूल्यांकन को प्रभावित करता है $ACTION
क्योंकि _less_important_function()
सेट $ACTION
केवल के माध्यम से होता है${parameter:=expansion}.
:शून्य
और मैं अग्रणी :colon?
खैर का उपयोग क्यों करता हूं , man
पृष्ठ आपको बताएगा कि : does nothing, gracefully.
आप देखते हैं, parameter expansion
वास्तव में यह कैसा लगता है - यह expands
उस मूल्य के लिए है ${parameter}.
जब हम एक चर सेट करते हैं जब हम ${parameter:=expansion}
इसके मूल्य के साथ छोड़ देते हैं - जो शेल करेगा लाइन में निष्पादित करने का प्रयास। अगर इसे चलाने की कोशिश की गई तो यह the cemetery
आप पर कुछ गलतियाँ करेगा। PLACE="${PLACE:="the cemetery"}"
उसी परिणाम का उत्पादन करेगा, लेकिन यह इस मामले में भी बेमानी है और मैंने उस शेल को प्राथमिकता दी: ${did:=nothing, gracefully}.
यह आपको ऐसा करने की अनुमति देता है:
echo ${var:=something or other}
echo $var
something or other
something or other
यहाँ-दस्तावेजों
और वैसे - एक अशक्त या परेशान चर की इन-लाइन परिभाषा यह भी है कि निम्नलिखित कार्य क्यों किए जाते हैं:
<<HEREDOC echo $yo
${yo=yoyo}
HEREDOC
yoyo
एक के बारे में सोचने का सबसे अच्छा तरीका है here-document
एक इनपुट फ़ाइल-डिस्क्रिप्टर पर स्ट्रीम की गई वास्तविक फ़ाइल है। कमोबेश यही वे हैं, लेकिन अलग-अलग गोले उन्हें थोड़ा अलग तरीके से लागू करते हैं।
किसी भी स्थिति में, यदि आप उद्धरण नहीं करते हैं, तो आप <<LIMITER
इसे स्ट्रीम में प्राप्त कर सकते हैं और मूल्यांकन किया जा सकता है expansion.
ताकि कैन here-document
काम में एक वैरिएबल की घोषणा कर सके, लेकिन केवल expansion
जिसके माध्यम से आप केवल वैरिएबल सेट करने के लिए सीमित कर सकते हैं जो पहले से सेट नहीं हैं। फिर भी, यह पूरी तरह से आपकी आवश्यकताओं के अनुरूप है जैसा कि आपने उन्हें वर्णित किया है, क्योंकि जब आप अपने टेम्पलेट प्रिंट फ़ंक्शन को कॉल करते हैं तो आपके डिफ़ॉल्ट मान हमेशा सेट होंगे।
क्यों नहीं eval?
खैर, मैंने जो उदाहरण प्रस्तुत किया है वह स्वीकार करने का एक सुरक्षित और प्रभावी साधन प्रदान करता है parameters.
क्योंकि यह गुंजाइश को संभालता है, सेट के माध्यम से प्रत्येक चर ${parameter:=expansion}
बाहर से निश्चित है। इसलिए, यदि आप यह सब एक स्क्रिप्ट में डालते हैं, जिसे कहा जाता है template_pr.sh और भाग गया:
% RESULT=something_else template_pr.sh
आपको मिलेगा:
मैं आपकी माँ के घर गया और बर्फ पर डिज्नी को देखा
यदि आप सुलेख करते हैं तो आप some_else करेंगे
मैं कब्रिस्तान गया और बर्फ पर डिज्नी को देखा
यदि आप उपचारात्मक गणित करते हैं तो आप some_else करेंगे
मैं कब्रिस्तान गया और बर्फ पर डिज्नी को देखा
यदि आप उपचारात्मक गणित करते हैं तो आप some_else करेंगे
यह उन चरों के लिए काम नहीं करेगा जो शाब्दिक रूप से स्क्रिप्ट में सेट थे, जैसे कि $EVENT, $ACTION,
और $one,
लेकिन मैंने केवल अंतर प्रदर्शित करने के लिए उन तरीकों को परिभाषित किया था।
किसी भी मामले में, एक evaled
बयान में अज्ञात इनपुट की स्वीकृति स्वाभाविक रूप से असुरक्षित है, जबकि parameter expansion
विशेष रूप से इसे करने के लिए डिज़ाइन किया गया है।