You may say "shell environment" about the environment of the current shell, which includes the current environment variables. The environment is inherited by any started sub-process (subshell or otherwise).
The "shell context" is a term not commonly used, but I'm assuming it would be equivalent of the "process context". In the case of a shell script, this would include the shell environment as well as the current shell variables, file descriptors (standard input, standard output and standard error, and any others explicitly opened), signal handlers (installed with trap
) etc. If it was a C program, the process context would be inherited across a call to fork()
, but not across a subsequent exec()
call (only the environment would survive a call to exec()
).
When you run your hello
program, which I'm assuming is a shell script, the input and output happens in the context of the shell that is executing the hello
script. This is "the current shell". The shell that you typed ./hello
into is its parent shell, and hello
inherits its environment.
Internally, the parent shell does a fork()
and exec()
call to start the shell that will eventually run the hello
script.
The fact that the hello
script is prompting in the same terminal as where you started the script just means that the shell running the script is the current foreground process there. The parent shell is waiting for it to finish. When it finishes, the parent shell will once again be the foreground process in the terminal.
When you start the script with source ./hello
or . ./hello
, the script executes in the same context as the shell you typed that command into. This means that it may modify the context and environment of the interactive shell. For example, it may change the current working directory (changes the environment) or install a signal handler (changes the context), and those changes would still be "active" when the script finishes executing.
If the hello
program is a compiled binary, it will inherit the environment of the invoking shell, but will not share its context (file descriptors etc.). It is not really running in a subshell since it's not a shell script. The parent shell will move into the background, waiting for the program to finish, just like it would do for a shell script. From the point of view of the parent shell, there is no difference between starting a compiled binary or a shell script.
A compiled binary may not be started with source
or .
(dot) since the shell does not know how to interpret a binary file.
There is a bit of hand waving in this answer, but I believe it's basically correct. Please leave a comment (or edit) if anything needs correcting or adding.