Expanding on the (currently accepted) answer from redneb...
TL;DR Need to source a script with no positional arguments within another script? try function DoSource() { source test.sh ; } ; DoSource instead of just source test.sh.
sourceing a script with no arguments within another script
The excerpt from Bash manual in the question shows the details of how the positional parameters are assigned to the sourced script. In particular, if the source command does not specify any argument, it is assigned the ones from the calling environment.
A consequence is that it may be troublesome to source a script passing no arguments within another script.
For example, let's use redneb example as test.sh:
echo "I was given $# argument(s):"
printf "%s\n" "$@"
sourced within another script userScript.sh, which is e.g. the one-liner:
source test.sh
When running an example like above:
$ bash userScript.sh a 'b c'
I was given 2 argument(s):
a
b c
test.sh inherits userScript.sh positional arguments... which now is not what I want (if I did, I could have used source test.sh "$@").
I have found the following to be a useful workaround: encapsulate the source command into a Bash function. The new userScript.sh looks like:
function DoSource() { source test.sh ; }
DoSource
reports:
$ bash userScript.sh a 'b c'
I was given 0 argument(s):
Note that specifying an empty argument (source test.sh '') is not equivalent, since the empty argument would be passed to test.sh.
If the sourcing script is also expected to be sourced
If userScript.sh itself is supposed to be sourced, then one probably does not want to leave DoSource() around. In that case, the simple solution is self destruction:
function _userScript_sh_DoSource() { source test.sh ; unset "$FUNCNAME" ; }
_userScript_sh_DoSource
for one-time-only usage (function name has been chosen to reduce the chance of name conflicts); or a unset _userScript_sh_DoSource command can be places after _userScript_sh_DoSource is not needed any more.
Flexible variant for multiple use
A more complex variant of DoSource():
function DoSource() { local ScriptName="$1" ; shift ; source "$ScriptName" ; }
DoSource test1.sh
DoSource test1.sh "$@"
DoSource test2.sh
can be used as a "drop-in" replacement for source, with the only difference being that when no positional argument is specified for the script to be sourced, source inherits them, while DoSource uses none.
Note however that DoSource is a function and as such behaves differently from source in other aspects (e.g. stack call, FUNCNAME, ...).