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++:
void boo(int &myint) { myint = 5; } int main() { int t = 4; printf("%d\n", t); // t->4 boo(t); printf("%d\n", t); // t->5 }
So then in BASH I want to do something like:
function boo () { var1=$1 # now var1 is global to the script but using it outside # this function makes me lose 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
Any thoughts would be appreciated.
The advantage of passing an argument ByRef is that the procedure can return a value to the calling code through that argument. The advantage of passing an argument ByVal is that it protects a variable from being changed by the procedure.
The call by reference method of passing arguments to a function copies the reference of an argument into the formal parameter. Inside the function, the reference is used to access the actual argument used in the call. This means that changes made to the parameter affect the passed argument.
The main difference between pass by value and pass by reference is that, in a pass by value, the parameter value copies to another variable while, in a pass by reference, the actual parameter passes to the function. A computer program is a set of instructions that directs the CPU to perform a certain task.
Pass by reference allows us to pass arguments to a function without making copies of those arguments each time the function is called.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With