In order to run a program (whether it's a bash script, or binary executable), you need to have execute permissions. When you enter a command, the first word (such as ./foo
in the below) specifies the command to run, and that is started up as a separate process; in the case of a shell script, it executes a new copy of the shell interpreter listed on the #!
line, and runs the program using that interpreter.
$ ls -l foo
-rw-r--r-- 1 lambda lambda 23 Mar 25 20:02 foo
$ chmod 744 foo # or chmod u+x foo
$ ls -l foo
-rwxr--r-- 1 lambda lambda 23 Mar 25 20:02 foo
$ ./foo
Hello
When you use the .
command, that is a shell builtin command that says to source the file into the current shell; that means that it executes the commands in the file as if you had run them from the command line, right in the current file. You need only read permission to source a file. For example, if you set a variable in a sub-process, it doesn't change the value in the current shell; but if you source a bash script into the current shell, then it does change the value:
$ foo=bar
$ cat setvariables
#!/bin/sh
foo=hello
$ ./setvariables
$ echo $foo
bar
$ . ./setvariables
$ echo $foo
hello
A shell function (like in your example) is a lot like a variable, but it acts like a command in the current shell. So, when you source your hello_file
using .
, that defines that function in the current shell, and it can execute like any other shell function you have defined.
As far as the permissions are concerned, I would bet that before changing the permissions to 100 (which means only executable, not readable, which is fairly useless for a file since you need to be able to read it and execute it to do anything), you had already sourced the file into your current shell. That would mean that the function was already defined, and it doesn't matter the permissions of the file after it's defined; once the function is defined in the current shell, you can even delete the file, and as long as that shell is still open, the function will still be defined.
Edit: As I see from your edited question, once you unset the function, you get an error. That indicates strongly to me that my hypothesis was correct, and that you had already sourced the file before you changed permissions. As I explained, sourcing and executing the file are entirely different operations, and once you source a file, its permissions (or existence) don't matter at all; the function has already been loaded into the currently running shell. You can tell by running your original experiment after doing the unset hello
; if you chmod 000
it, you shouldn't have read permissions, and then the function won't be defined.