Issue
Please notice that I'm talking about passing arguments by-ref to a script, not to a function. I already checked href="https://stackoverflow.com/questions/540298/passing-arguments-by-reference">here and here and they discuss about passing arguments using functions.
What I want is to call a script passing an argument to it and having the argument becoming a variable in the shell with the value assigned inside the script (which is exactly what happens with the read RESPONSE
command, where RESPONSE becomes a variable in the current shell with the value assigned by the read
command).
I know that using functions like this (using local -n
):
#!/bin/bash
function boo() {
local -n ref=$1
ref="new"
}
SOME_VAR="old"
echo $SOME_VAR
boo SOME_VAR
echo $SOME_VAR
or like this (using eval
):
function booeval() {
ref=$1
eval $(echo $ref=\"new\")
}
SOME_VAR="old"
echo $SOME_VAR
booeval SOME_VAR
echo $SOME_VAR
work as expected. But local
(or declare
/typedef
) doesn't work outside of a function and eval
seems to run in a subshell that when the script is over the variable doesn't survive in the shell. I wanted to have something like this:
$ cat /tmp/test.sh
#!/bin/bash
ref=$1
eval $(echo "export $ref=\"new value\"")
$ /tmp/test.sh VAR
$ echo $VAR
$
Any ideas?
Solution
Thank you all for the effort in answering the question. I will end up going with the gdb
option to set the environmental variable using the parameters passed as arguments. As long as I do sudo, it will work just fine.
This is not intended to be a solution to be used without a lot of caution as you would be calling internal bash functions and things could be messed up. But in general it will run just fine.
Checking some ways to unset read-only variables, I stumbled upon using gdb to call the unbind_variable()
function directly. So, I applied the same logic and set a new variable from the script. It "kinda" works, but not smoothly:
$ cat /tmp/test.sh
#!/bin/bash
ref="$1"
value="Value assigned from inside the script"
bashpid=$(ps -oppid,pid,cmd | grep $0 | grep -v grep | cut -f1 -d' ')
sudo gdb -ex 'call (int) setenv("'"$ref"'","'"$value"'",1)' --pid=$bashpid --batch 2>/dev/null 1>&2
And when I call it:
$ declare -p VARPASSED
bash: declare: VARPASSED: not found
$ /tmp/test.sh VARPASSED
$ declare -p VARPASSED
declare -x VARPASSED="Value assigned from inside the script"
Now the variable passed is correctly assigned to the current shell. The problem is that gdb requires sudo
to attach to the current shell, which is a little bit annoying. How did they do with the read
command?
PS: please cut some slack on the way to get the bash pid, I know there are much more efficient ways to do it. That was just not my focus ;)
Answered By - Adriano_Pinaffo Answer Checked By - Dawn Plyler (WPSolving Volunteer)