It is not totally rigth that I can run a Bash function with 000 permissions, but almost. My code is:
#!/bin/bash function hello { echo Hello! }
The hello-file has permissions:
-r-------- 1 UnixBasics hello_file
Firtsly, I type with the current permissions:
$ . ./hello_file;hello
The tweak is to change the 400 permissions to 000 right before running the bash script script:
$ chmod 000 hello_file $ . ./hello_file;hello [1] -bash: ./hello_file: Permission denied Hello!
It gives one error, but it does not stop running the function. I cannot understand. I now unset the hello-function: ‘unset hello’. I receive the errors:
-bash: ./hello_file: Permission denied -bash: hello: command not found
Why did I not get them at the first time? Has it something to do with cache, buffer or something like it? Why can I run the Bash script with 000 permissions [1]?
You are not running the script, you are sourcing (including) it. In order to source a script, you only need the read permission.
By the way, functions simply exist, they don’t have permission. Once the file was sourced and the function defined, you can run it as much as you want.
Update:
Yes, like Pax answered, hello was probably previously defined there from a previous sourcing of the file. You may be confused with what sourcing (‘.’ builtin command) does. Sourcing reads the file and runs all its commands in the current shell, then goes back to the prompt. So, if you run the file once, its functions are defined in the current shell instance, and they stay there until you finish that shell session (or unset them).
You can’t. Note that it presents an error. Quoting your output:
You executed two commands in a single command-line. The sourcing failed with ‘Permission denied’. The ‘Hello!’ output is from a previous sourcing of the file. You just proved it yourself when you unset it and tried the same command-line again.
You can’t call that caching… it is how the shell works. You source another file, all its definitions are included in the current shell session and stay there. If you actually run the script (not sourcing) you shouldn’t get any residues in the current session.