2011-12-08 10 views
21

क्या किसी अज्ञात फ़ंक्शन के समान कुछ बनाना संभव है जिसका मूल्य किसी सरणी तत्व को असाइन किया जा सकता है और बाद में कहा जाता है? मुझे बैश स्क्रिप्ट में ऐसा करने का कोई तरीका नहीं दिख रहा है लेकिन शायद एक कामकाज है।शैल स्क्रिप्ट्स में बेनामी फ़ंक्शन

उत्तर

47

लघु जवाब: नहीं

लांग जवाब: Nooooooooooooo।

पूरा उत्तर: बैश में कार्य प्रथम श्रेणी की वस्तुएं नहीं हैं, इसलिए बैश में अज्ञात फ़ंक्शन जैसी कोई चीज़ नहीं हो सकती है।

+5

कामकाज के रूप में, मैं नामों के साथ कार्यों को परिभाषित करता हूं और केवल सरणी में नाम संग्रहीत करता हूं; फिर जब आप फ़ंक्शन को कॉल करना चाहते हैं तो सरणी तत्व को केवल 'eval' करें। – choroba

+1

@choroba शायद आपको इसे एक उत्तर के रूप में पोस्ट करना चाहिए। यद्यपि इग्नासिओ के वर्णन के रूप में यह संभव नहीं है, आपका कामकाज एक अच्छा विचार है। – Matty

+0

क्या सीवीई-2014-6271 [लिंक] में बश बग है (https://www.reddit.com/r/netsec/comments/2hbxtc/cve20146271_remote_code_execution_through_bash/ckrhvtl) पुष्टि करें कि अज्ञात फ़ंक्शन शैल स्क्रिप्ट में मौजूद हो सकते हैं? – Lizz

5

आम तकनीक सशर्त समारोह परिभाषाओं आवंटित करने के लिए है:

 
#!/bin/sh 

case $1 in 
a) foo() { echo case a; };; 
b) foo() { echo case b; };; 
*) foo() { echo default; } ;; 
esac 

foo 
8

तुम सच में काम करता है स्टोर करने के लिए सरणी की जरूरत है, तो आप नामित कार्यों को परिभाषित और सिर्फ उनके नाम स्टोर कर सकते हैं। फिर आप फ़ंक्शन को ${array[n]} के रूप में कॉल कर सकते हैं। या, आप उन्हें func1 .. funcN नाम कर सकते हैं और फिर बस func$n कहते हैं।

7

यह संभव है; मैंने वास्तव में ऐसा करने के लिए एक पुस्तकालय लिखा, हालांकि यह एक बहुत ही अजीब परियोजना है। स्रोत कोड http://github.com/spencertipping/bash-lambda पर उपलब्ध है। इस पुस्तकालय का उपयोग करना:

$ my_array=() 
$ my_array[0]=$(fn x 'echo $((x + 1))') 
$ my_array[1]=$(fn x 'echo $((x + 2))') 
$ ${my_array[0]} 5 
6 
$ ${my_array[1]} 5 
7 
$ 

चाल fn समारोह समारोह, chmod +x कि फाइल के शरीर वाली फ़ाइल बनाने, फिर उसके नाम वापसी है। इससे भटकने वाली फाइलें जमा हो जाती हैं, यही कारण है कि लाइब्रेरी एक असीमित चिह्न/स्वीप कचरा कलेक्टर भी लागू करती है।

+0

वहाँ गुमनाम समारोह निष्पादित करने से पहले क्रियान्वित परिष्करण के लिए एक आदेश के लिए प्रतीक्षा करने के लिए एक रास्ता है? – William

0

अपने PATH

#!/bin/sh 

printusage() { 
     printf "Create anonymous function, for example\n" 
     printf "fn 'echo "$1 $2"'" 
     exit 1 
} 


[ "$#" = "1" ] || printusage 
fun=$1 
[ "$fun" = "" ] && printusage 
fun_file="$(mktemp /tmp/fun_XXXXXX)" 

echo "#!/bin/sh" > "$fun_file" 
echo "" >> "$fun_file" 
echo "$fun" >> "$fun_file" 
chmod u+x "$fun_file" 

echo "$fun_file" 

में fn फ़ाइल बनाएँ इसके बाद आप कर सकते हैं:

foo=$(fn 'echo $1') 
${foo} "bar" 
0

अच्छी तरह से पार्टी ट्यूरिंग पूरा हो गया है, सू पूरी तरह से संभव thats;)

लेकिन एक तरफ इस से यह वास्तव में विचार के लायक नहीं है।

आप इस रेखा के साथ कुछ के साथ इस तरह के व्यवहार हालांकि अनुकरण कर सकते हैं:

echo myval ; (foocmd "$_" && barcmd "$_") 

लेकिन क्यों?!?

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