2011-12-08 94 views
21

是否可以創建類似於匿名函數的值,該函數的值可以分配給數組元素並稍後調用?我似乎無法找到在bash腳本中執行此操作的方法,但也許有一種解決方法。shell腳本中的匿名函數

回答

47

簡短的回答:第

龍答:Nooooooooooooo。

完整答案:在bash中的函數不是一流的對象,因此在bash中不能有這樣的事情。

+5

作爲一種解決方法,我會用名稱定義函數並在數組中存儲名稱;那麼當你想調用該函數時,只需'調用'數組元素。 – choroba

+1

@choroba或許你應該發佈這個答案。儘管Ignacio所描述的並非直接可行,但您的解決方法是一個好主意。 – Matty

+0

CVE-2014-6271 [link](https://www.reddit.com/r/netsec/comments/2hbxtc/cve20146271_remote_code_execution_through_bash/ckrhvtl)中的bash錯誤是否證實匿名函數可以存在於shell腳本中? – 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

創建FN文件在您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" 

那麼你可以這樣做:

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

以及慶典是圖靈完備,洙那是完全可能的;)

但除了這它不值得考慮。

你可以模仿這種行爲雖然具有沿着這條線的東西:

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

但爲什麼呢?!?