2011-12-08 53 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 "$_") 

但为什么呢?!?