I mean to have:
A bash script
scr.shthat takes positional parameters#!/bin/bash echo "Params = $@" echo REMOTE_SERVER=${REMOTE_SERVER}A bash function
fdefined in another scriptscr2.sh#!/bin/bash f() { REMOTE_SERVER=s001 scr.sh "${@}" }
I would first
$ source scr2.shand then have f available for calling at the command line, but not leaving a trace of what I did with REMOTE_SERVER. For instance, I want
$ f par1 par2
par1 par2
s001
$ echo REMOTE_SERVER=${REMOTE_SERVER}
REMOTE_SERVER=(actually, if REMOTE_SERVER was set before using f, I want it to keep that value). I couldn't attain this last objective. I always end up with REMOTE_SERVER set.
I tried using multiline commands separated with a semicolon, enclosing commands inside f with parenthesis, but it didn't work.
How can I do that?
2 Answers
If you want to set a variable only for a command, prefix the assignment to the command:
REMOTE_SERVER=s001 scr.sh "${@}"Alternately, use a subshell for the function (then variable assignments won't affect the parent shell). You can create a subshell by wrapping commands in ( ... ) (parentheses), or using parentheses instead of braces for the function body. For example, with:
foo () ( REMOTE_SERVER=s001
)
bar () { REMOTE_SERVER=s001
}
foo; echo "REMOTE_SERVER=$REMOTE_SERVER"; bar; echo "REMOTE_SERVER=$REMOTE_SERVER"; My output would be:
REMOTE_SERVER=
REMOTE_SERVER=s001 Using
#!/bin/bash
f() { ( REMOTE_SERVER=s001 scr.sh "${@}" )
}works fine. This is likely equivalent to the accepted answer, with the extra flexibility of including parts of the code inside the local shell and parts outside.