我想询问是否可以通过引用传递脚本函数的参数:
即在C中做一些这样的事情:
Void boo (int & myint) { myint= 5; } main (){ int t= 4; printf t; // t->4 boo (t); printf t; // t ->5 }
那么在BASH我想做一些像:
Function boo () { var1=$1 # now var1 is global to the scrip but using it outside # this function makes me loose encapsulation local var2=$1 # so i should use a local variable ... but how to pass it back ? var2='new' # only changes the local copy #$1='new' this is wrong of course ... # ${!1}='new' # can i somehow use indirect reference? } # call boo SOME_VAR='old' echo $SOME_VAR # -> old boo "$SOME_VAR" echo $SOME_VAR # -> new
任何想法都不胜感激。
使用助手功能upvar:
# Assign variable one scope above the caller. # Usage: local "$1" && upvar $1 value [value ...] # Param: $1 Variable name to assign value to # Param: $* Value(s) to assign. If multiple values,an array is # assigned,otherwise a single value is assigned. # NOTE: For assigning multiple variables,use 'upvars'. Do NOT # use multiple 'upvar' calls,since one 'upvar' call might # reassign a variable to be used by another 'upvar' call. # See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference upvar() { if unset -v "$1"; then # Unset & validate varname if (( $# == 2 )); then eval $1=\"\$2\" # Return single value else eval $1=\(\"\${@:2}\"\) # Return array fi fi }
并在Newfun()中使用它:
local "$1" && upvar $1 new
为了返回多个变量,请使用另一个帮助函数upvars。这允许在一个调用中传递多个变量,从而避免如果一个upvar调用更改另一个后续upvar调用中使用的变量的可能冲突。
请参阅:http://www.fvue.nl/wiki/Bash:_Passing_variables_by_reference for helper function upvars和更多信息。
问题在于:
eval $1=new
是否如果$ 1碰巧包含一个命令是不安全的:
set -- 'ls /;true' eval $1=new # Oops
最好使用printf -v:
printf -v "$1" %s new
但是printf -v不能分配数组。
此外,如果变量恰好被声明为local,那么eval和printf都不会工作:
g() { local b; eval $1=bar; } # WRONG g b # Conflicts with `local b' echo $b # b is empty unexpected
即使本地b未设置,冲突仍然存在:
g() { local b; unset b; eval $1=bar; } # WRONG g b # Still conflicts with `local b' echo $b # b is empty unexpected