Passing arguments by reference

后端 未结 9 1912
挽巷
挽巷 2020-12-01 01:13

I want to ask if it is possible to pass arguments to a script function by reference:

i.e. to do something that would look like this in C++:



        
相关标签:
9条回答
  • 2020-12-01 02:02

    This is what works for me on Ubuntu bash shell

    #!/bin/sh
    
    iteration=10
    
    increment_count()
    {
      local i
      i=$(($1+1))
      eval ${1}=\$i
    }
    
    
    increment_count iteration
    echo $iteration #prints 11
    increment_count iteration
    echo $iteration #prints 12
    
    0 讨论(0)
  • 2020-12-01 02:03

    It's 2018, and this question deserves an update. At least in Bash, as of Bash 4.3-alpha, you can use namerefs to pass function arguments by reference:

    function boo() 
    {
        local -n ref=$1
        ref='new' 
    }
    
    SOME_VAR='old'
    echo $SOME_VAR # -> old
    boo SOME_VAR
    echo $SOME_VAR # -> new
    

    The critical pieces here are:

    • Passing the variable's name to boo, not its value: boo SOME_VAR, not boo $SOME_VAR.

    • Inside the function, using local -n ref=$1 to declare a nameref to the variable named by $1, meaning it's not a reference to $1 itself, but rather to a variable whose name $1 holds, i.e. SOME_VAR in our case. The value on the right-hand side should just be a string naming an existing variable: it doesn't matter how you get the string, so things like local -n ref="my_var" or local -n ref=$(get_var_name) would work too. declare can also replace local in contexts that allow/require that. See chapter on Shell Parameters in Bash Reference Manual for more information.

    The advantage of this approach is (arguably) better readability and, most importantly, avoiding eval, whose security pitfalls are many and well-documented.

    0 讨论(0)
  • 2020-12-01 02:10

    Eval should never be used on a string that a user can set because its dangerous. Something like "string; rm -rf ~" will be bad. So generally its best to find solutions where you don't have to worry about it.

    However, eval will be needed to set the passed variables, as the comment noted.

    $ y=four
    $ four=4
    $ echo ${!y}
    4
    $ foo() { x=$1; echo ${!x}; }
    $ foo four
    4
    
    0 讨论(0)
提交回复
热议问题