我希望我可以做这样的事情,输出就是“你好”
#!/bin/bash
foo="hello"
dummy() {
local local_foo=`echo $foo`
echo $local_foo
}
foo=''
dummy
这个问题意味着我希望在定义时捕获某些全局值的值,通常通过source blablabla.bash
使用,并希望它定义一个捕获当前变量值的函数。
答案 0 :(得分:4)
函数在运行时进行评估,而不是在定义时进行评估。由于您希望捕获在定义时存在的变量,因此您需要在此时分配一个单独的变量。
foo="hello"
# By convention, global variables prefixed by a function name and double underscore are for
# the exclusive use of that function.
readonly dummy__foo="$foo" # capture foo as of dummy definition time, and prevent changes
dummy() {
local local_foo=$dummy__foo # ...and refer to that captured copy
echo "$local_foo"
}
foo=""
dummy
但是,如果你愿意犯下危害人类罪, 可以进行代码生成来捕获一个值。例如:
# usage: with_locals functionname k1=v1 [k2=v2 [...]]
with_locals() {
local func_name func_text assignments
func_name=$1; shift || return ## fail if out of arguments
(( $# )) || return ## noop if not given at least one assignment
func_text=$(declare -f "$func_name")
for arg; do
if [[ $arg = *=* ]]; then ## if we already look like an assignment, leave be
printf -v arg_q 'local %q; ' "$arg"
else ## otherwise, assume we're a bare name and run a lookup
printf -v arg_q 'local %q=%q; ' "$arg" "${!arg}"
fi
assignments+="$arg_q"
done
# suffix first instance of { in the function definition with our assignments
eval "${func_text/{/{ $assignments}"
}
...此后:
foo=hello
dummy() {
local local_foo="$foo"
echo "$local_foo"
}
with_locals dummy foo ## redefine dummy to always use the current value of "foo"
foo=''
dummy
答案 1 :(得分:0)
好吧,您可以注释掉或删除foo=''
行,这样就可以了。函数dummy
在您调用它之前不会执行,这是在您清空了foo
值之后,因此您可以回显一个空行。希望这会有所帮助。
答案 2 :(得分:0)
除非通过bash调用该函数,否则无法在函数内执行代码。只有一种方法可以调用其他函数来定义你想要调用的函数 这就是动态函数定义。
我不相信你想要那个。
另一种方法是存储foo的值(调用函数),然后在值更改后再次调用它。像这样的东西:
#!/bin/bash
foo="hello"
dummy() {
${global_foo+false} &&
global_foo="$foo" ||
echo "old_foo=$global_foo new_foo=$foo"
}
dummy
foo='new'
dummy
foo="a whole new foo"
dummy
调用它将打印:
$ ./script
old_foo=hello new_foo=new
old_foo=hello new_foo=a whole new foo
由于我不确定这是否解决了您的真正问题,只需:希望这会有所帮助。
答案 3 :(得分:0)
在受到@CharlesDuffy的启发之后,我认为使用eval可能会解决一些问题,并且示例可以修改如下:
#!/bin/bash
foo="hello"
eval "
dummy() {
local local_foo=$foo
echo \$local_foo
}
"
foo=''
dummy
哪会给你的结果'你好'而不是一无所获。
@CharlesDuffy指出这种解决方案非常危险:
local local_foo = $ foo是危险的错误:如果你的foo值包含 如$(rm -rf $ HOME)这样的扩展,它将被执行
使用eval可以提高性能,但安全性却很差。因此,我建议@CharlesDuffy给出答案。