I want to be able to call a function, and keep all the modifications that the function will perform on the string.
For example: I tried this script
#!/bin/bash
change_string() {
var=$1
var+=",Hello2"
echo "Function: $var"
}
myString="Hello1"
change_string $myString
echo "Main: $myString"
This will print out:
Function: Hello1,Hello2
Main: Hello1
Is there any way to change the $myString inside function call, but keep those changes in main? I think I probably missed something in bash related to pass-by-reference?
Modern versions of bash provide "nameref" support, which allows a variable to refer to another.
#!/usr/bin/env bash
case $BASH_VERSION in
[123].*|4.[012].*) echo "This needs bash 4.3 or newer" >&2; exit 1;;
esac
# local variable is prefixed because this will fail if we're passed a variable name we use
# internally; prefixing the local names makes such collisions unlikely.
change_string() {
# make change_string__var an alias for the variable named in our argument
declare -n change_string__var=$1
# append to that variable
change_string__var+=",Hello2"
# ...and log the new value, 'cuz that's what the original code did.
echo "Function: $change_string__var"
}
myString="Hello1"
change_string myString ## pass variable **name**, not variable value
echo "Main: $myString"
Alternately, as a less-newfangled approach, one can use ${!var}
to do an indirect reference, and printf -v
to do an indirect assignment.
#!/usr/bin/env bash
change_string() {
# Store the variable name in a regular local variable
local change_string__var=$1
# Use ${!var} to get the value of the variable thus named
local change_string__val=${!change_string__var}
# Use ''printf -v varname ...'' to assign a new value
printf -v "$change_string__var" %s "${change_string__val},Hello2"
}
myString="Hello1"
change_string myString
echo "Main: $myString"