2010-05-24 13 views
10

में निम्नलिखित से आलसी मूल्यांकन करने का और अधिक सुरुचिपूर्ण रास्ता नहीं है । क्या बैश में ऐसा करने का कोई बेहतर तरीका है?आलसी मूल्यांकन बैश

+0

मैं उत्सुक हूँ क्यों आप क्या करना चाहते तो इस प्रकार का उपयोग यह या वास्तव में आप इसे पूरा करने की कोशिश कर रहे हैं। कभी-कभी 'eval' जाने का सही या एकमात्र तरीका है, लेकिन' घोषणा 'और 'printf' की विशेष विशेषताएं भी उपयोगी हो सकती हैं। और आप जो भी कर रहे हैं उसे पूरा करने के अन्य तरीके हो सकते हैं। –

+0

मेरे पास एक बैश स्क्रिप्ट है जिसे मैं विन्यास योग्य बनाना चाहता हूं। मैं चाहता हूं कि उपयोगकर्ता को "पैटर्न" निर्दिष्ट करने की क्षमता हो। बाद में, पैटर्न में कुछ चर स्क्रिप्ट (एसक्यूएल प्रश्न, एसओएपी कॉल, और अन्य इन-हाउस यूटिलिटीज) द्वारा संचालित गतिविधियों के साथ प्रतिस्थापित किए जाएंगे और एक अन्य कमांड लाइन प्रोग्राम में पास हो जाएंगे। मैं बैश के लिए कुछ नया हूं और इस दृष्टिकोण के बारे में कुछ गलत लगता है। अधिक जानकारी पूछने के लिए धन्यवाद। – User1

उत्तर

4

जब तक अविश्वसनीय स्रोतों से मूल्य नहीं आते हैं, तब तक कोई सुरक्षा जोखिम नहीं होता है। वहाँ कुछ विकल्प है, हालांकि कर रहे हैं, तो आप उदाहरण के लिए, gettext से आदेश envsubst उपयोग कर सकते हैं:

expand_pattern() { 
    pattern="$x and $y" 
} 

सब है कि:

$ pattern='$x and $y' 
$ x=1 y=2 envsubst <<< $pattern 
1 and 2 
+0

मुझे लगता है कि इस मामले के लिए सुरक्षा सामान थोड़ा सा भयावह है। मुझे अतिरिक्त उद्धरण पसंद हैं। – User1

0

आप सही हैं, eval इस मामले में एक सुरक्षा जोखिम है। यहाँ एक संभव तरीका है: "। वेयरवोल्फ सक्रिय है जब चाँद भरा हुआ है और आसमान साफ"

pattern='The $a is $b when the $z is $x $c $g.' # simulated input from user (use "read") 
unset results 
for word in $pattern 
do 
    case $word in 
     \$a) 
      results+=($(some_command)) # add output of some_command to array (output is "werewolf" 
      ;; 
     \$b) 
      results+=($(echo "active")) 
      ;; 
     \$c) 
      results+=($(echo "and")) 
      ;; 
     \$g) 
      results+=($(echo "the sky is clear")) 
      ;; 
     \$x) 
      results+=($(echo "full")) 
      ;; 
     \$z) 
      results+=($(echo "moon")) 
      ;; 
      *) 
      do_something # count the non-vars, do a no-op, twiddle thumbs 
      # perhaps even sanitize %placeholders, terminal control characters, other unwanted stuff that the user might try to slip in 
      ;; 
    esac 
done 
pattern=${pattern//\$[abcgxz]/%s} # replace the vars with printf string placeholders 
printf "$pattern\n" "${results[@]}" # output the values of the vars using the pattern 
printf -v sentence "$pattern\n" "${results[@]}" # put it into a variable called "sentence" instead of actually printing it 

उत्पादन होगा एक ही कार्यक्रम, यदि पैटर्न '$ x $ z $ c $ g से बाहर है, तो $ एक $ बी होना चाहिए।' तो आउटपुट होगा "पूर्णिमा बाहर है और आकाश स्पष्ट है, इसलिए वेयरवोल्फ सक्रिय होना चाहिए।"

+1

उत्तर प्रश्न के उदाहरण से मेल खाता है। लेकिन यह मूल स्ट्रिंग प्रतिस्थापन के लिए और भी जटिल के लिए बहुत उपयोगी प्रतीत नहीं होता है। अगर मैं इस दृष्टिकोण का पालन करने की कोशिश करता हूं, तो मुझे बैश में एक बैश दुभाषिया लिखना होगा। – ceving

+0

मेरा उत्तर किसी उपयोगकर्ता के अविश्वसनीय इनपुट से स्क्रिप्ट को अपनाने का एक तरीका है। यह मेरी क्वेरी के जवाब में प्रश्न से जुड़ी ओपी की टिप्पणी पर आधारित है। –

2

एक सुरक्षित संभावना एक समारोह का प्रयोग है।

x=1 y=1 
expand_pattern 
echo "$pattern" 

तुम भी x और y वातावरण चर के रूप में उपयोग कर सकते हैं (ताकि वे मुख्य दायरे में सेट नहीं हैं):

x=1 y=1 expand_pattern 
echo "$pattern" 
+1

यह वह जवाब है जिसे मैं लिखने जा रहा था अगर यह पहले से ही नहीं था। (फिर फिर से, मैंने केवल इस प्रश्न को उत्तर के जवाब के आधार पर देखा, इसे सामने वाले पृष्ठ पर वापस उछाल दिया)। :) –

संबंधित मुद्दे