Lets say I have a shell script (my-script.sh
)starting with:
#!/bin/sh
If the script has execute permissions set then I can run the script with:
./my-script.sh
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 ...
/bin/sh ./my-script.sh
... 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
and . ./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.
Further reading:
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 (#!
) https://en.wikipedia.org/wiki/Shebang_(Unix)
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
./ script
requires the script to be executable. – Tran Triet Feb 18 '19 at 13:47. ~/.bash_history
instead of. ~/.bash_profile
, for example? https://twitter.com/munificentbob/status/1091220194020622336 – Joker_vD Feb 18 '19 at 15:55