Bash – 通过引用传递参数

我想询问是否可以通过引用传递脚本函数的参数:

即在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

相关文章

普通模式 >G 增加当前行到文档末尾处的缩紧层级 $ 移动到本行的末尾 . 相当于一个...
原文连接: https://spacevim.org/cn/layers/lang/elixir/ 模块简介 功能特性 启用模块 快捷键 语言专属...
原文连接: https://spacevim.org/cn/layers/lang/dart/ 模块简介 功能特性 依赖安装及启用模块 启用模...
 =   赋值操作符,可以用于算术和字符串赋值 +        加法计算     -        减法运算...
1.根据包名来查看指定的APP指定数据 adb shell "top | grep com.xxx.xxx" 由于这样打印出来的数...
ctrl+F 向下翻页 ctrl+B 向下翻页 u 取消最近一次操作 U 取消当前行的操作 ZZ 保存当前内容并退出 gg 跳...