Lets say I have a shell script (
If the script has execute permissions set then I can run the script with:
In this case you are ultimately asking the kernel to run
my-script.sh as a program, and the kernel (program loader) will check permissions first, and then use
/bin/sh ./my-script.sh to actually execute your script.
But the shell (
/bin/sh) does not care about execute permissions and doesn't check them. So if you call this ...
... The kernel is never asked to run
my-script.sh as a program. The kernel (program loader) is only asked to run
/bin/sh. So the execute permissions will never me checked. That is, you don't need execute permission to run a script like this.
To answer your question:
The difference between you calling
. ./my-script.sh inside another script is exactly the same. In the first, you are asking the kernel to run it as a program, in the second, you are asking your current shell to read commands from the script and the shell doesn't need (or care about) execute permissions to do this.
Running scripts as programs is surprising behaviour when you think about it. They are not written in machine code. I would read up on why this works; start with reading up on the shebang (
Running scripts with the dot notation is necessary to share variables. All other mechanisms for running start a new shell "context", meaning that any variables set in the called script will not be passed back to the calling script. Bash documentation is a little lite, but it's here: https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html