The difference between sourcing (
. test.sh) the script and running it (
./test.sh) is in the first line.
If you source the script the first line is only a comment and ignored. But if you run it, the first line is examined by the kernel for the first two characters, and if they are "
#!", the rest of the line will be used as the path and the first argument for an interpreter. That is the kernel will look for an executable named
/bin/bash and pass it the name of the script as first argument. Like this:
This is what normally would happen and you are right, it should have the same effect for your script. But your script contains a problem: The first line ends with a DOS line ending (CR LF) instead of a unix line ending (LF). So the name of the interpreter, as the kernel sees it is
/bin/bash^M which does not exist on your disk (^M stands for the spurious CR before the line ending). To make matters worse, the ^M character is usually invisible.
You can prove that this is the case with
cat -v test.sh (which prints the substitution ^M for the invisible CR character).