1

I'm running a simple executable called hello in bash. It queries a user for input and prints out a response. I run it like so ./hello.

Both the prompting and user typing his response takes place in the current shell but I thought it was supposed to run in a different shell. I assumed this because you can use source to run the exe in the current shell.

Can anyone explain how this works to me?

In trying to research this I've often come across the terms "shell environment" and "shell context". Are they the same thing?

jtht
  • 113
  • 4

1 Answers1

3

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.

ilkkachu
  • 138,973
Kusalananda
  • 333,661
  • 'hello' is c++ binary, does that change anything? – jtht May 26 '17 at 19:03
  • @ÞórÓðinsson Not really. I have added a couple of bits of text to the answer. – Kusalananda May 26 '17 at 19:23
  • Bash's manual uses the phrase "execute ... in the current shell context" for ./source so it's used there. The POSIX text says "in the current environment". – ilkkachu May 26 '17 at 22:22
  • @ÞórÓðinsson When the program is a compiled executable, there is no shell executing it. The parent shell is starting it, but it is not executing in a shell. Scripts are running in shells, because a shell is needed to interpret the script. A compiled executable needs no interpreter. bash itself is a compiled executable, as is most other commands and applications. They need no shell te run. – Kusalananda May 27 '17 at 07:01