cd1*_*cd1 76 bash function callback parameter-passing
我需要在Bash中传递函数作为参数.例如,以下代码:
function x() {
echo "Hello world"
}
function around() {
echo "before"
eval $1
echo "after"
}
around x
Run Code Online (Sandbox Code Playgroud)
应输出:
before
Hello world
after
Run Code Online (Sandbox Code Playgroud)
我知道eval在那种情况下不正确,但这只是一个例子:)
任何的想法?
Ide*_*lic 106
如果您不需要延迟评估函数名称或其参数的任何想法,则不需要eval:
function x() { echo "Hello world"; }
function around() { echo before; $1; echo after; }
around x
Run Code Online (Sandbox Code Playgroud)
做你想要的.您甚至可以通过这种方式传递函数及其参数:
function x() { echo "x(): Passed $1 and $2"; }
function around() { echo before; "$@"; echo after; }
around x 1st 2nd
Run Code Online (Sandbox Code Playgroud)
版画
before
x(): Passed 1st and 2nd
after
Run Code Online (Sandbox Code Playgroud)
uDu*_*ude 22
我认为没有人能回答这个问题.他没有问他是否能按顺序回应弦乐.相反,问题的作者想知道他是否可以模拟函数指针行为.
有几个答案很像我要做的,我想用另一个例子来扩展它.
来自作者:
function x() {
echo "Hello world"
}
function around() {
echo "before"
($1) <------ Only change
echo "after"
}
around x
Run Code Online (Sandbox Code Playgroud)
为了扩展它,我们将使用函数x echo"Hello world:$ 1"来显示函数执行何时真正发生.我们将传递一个字符串,该字符串是函数"x"的名称:
function x() {
echo "Hello world:$1"
}
function around() {
echo "before"
($1 HERE) <------ Only change
echo "after"
}
around x
Run Code Online (Sandbox Code Playgroud)
为了描述这一点,字符串"x"被传递给around()函数,其中回显"之前",调用函数x(通过变量$ 1,传递给周围的第一个参数)传递参数"HERE",最后回显echos .
另外,这是使用变量作为函数名称的方法.变量实际上包含作为函数名称的字符串,并且($ variable arg1 arg2 ...)调用传递参数的函数.见下文:
function x(){
echo $3 $1 $2 <== just rearrange the order of passed params
}
Z="x" # or just Z=x
($Z 10 20 30)
Run Code Online (Sandbox Code Playgroud)
给出:30 10 20,其中我们执行了存储在变量Z中的名为"x"的函数,并传递了参数10 20和30.
上面我们通过为函数指定变量名来引用函数,所以我们可以使用变量来代替实际知道函数名(这与你在c中非常经典的函数指针情况中可能做的类似,用于概括程序流但是pre - 根据命令行参数选择您将要进行的函数调用.
在bash中,这些不是函数指针,而是引用您以后使用的函数名称的变量.
kur*_*umi 16
没有必要使用 eval
function x() {
echo "Hello world"
}
function around() {
echo "before"
var=$($1)
echo "after $var"
}
around x
Run Code Online (Sandbox Code Playgroud)
您不能将任何内容传递给字符串以外的函数.流程替换可以有点伪造它.Bash倾向于保持打开FIFO直到命令扩展完成.
这是一个快速愚蠢的
foldl() {
echo $(($(</dev/stdin)$2))
} < <(tr '\n' "$1" <$3)
# Sum 20 random ints from 0-999
foldl + 0 <(while ((n=RANDOM%999,x++<20)); do echo $n; done)
Run Code Online (Sandbox Code Playgroud)
可以导出函数,但这并不像它第一次出现那么有趣.我发现它主要用于使脚本或运行脚本的其他程序可以访问调试功能.
(
id() {
"$@"
}
export -f id
exec bash -c 'echowrap() { echo "$1"; }; id echowrap hi'
)
Run Code Online (Sandbox Code Playgroud)
id 仍然只获取一个恰好是函数名称的字符串(从环境中的序列化中自动导入)及其args.
Pumbaa80对另一个答案的评论也很好(eval $(declare -F "$1")),但它主要用于数组,而不是函数,因为它们总是全局的.如果你要在一个函数中运行它,它所做的就是重新定义它,所以没有任何效果.它不能用于创建闭包或部分函数或"函数实例",这取决于当前作用域中发生的任何事件.最好这可用于将函数定义存储在字符串中,并在其他地方重新定义 - 但这些函数也只能进行硬编码,除非当然eval使用
基本上Bash不能像这样使用.