8

I'm trying to grasp the concepts of shell and terminal and the exact relation between them from the aspect of OS processes. So I have few questions in that field.

  1. Sanity check: As far as I understand, the shell is the interface through which the user can interact with the OS, i.e.: run other processes. Although the shell (e.g. Bash) is just another process. Is that right?

  2. Is there a way to run a process that will not be a child of a shell process?

  3. Environment variables: In bash, there are several scripts that run when you spawn a shell, e.g. .bashrc, .bash_profile, etc. (depends on the type of shell - interactive vs non-interactive, login vs non-login). These scripts define the environment variables. If there's a way to run a process regardless to any shell, where do environment variables come from?

3
  • 10
    #2: Yes, there logically must be such a way, otherwise how would you run a shell? Dec 15, 2020 at 6:53
  • 1
    @JörgWMittag: There could be an OS where the shell is in a different class than other processes and is invoked in a different way. (e.g. DCL in OpenVMS seems slightly more special than other programs...)
    – user1686
    Dec 15, 2020 at 16:17
  • @user1686: True. My comment pre-supposes that the answer to #1 is "Yes" (which is true on Unix and most of its sisters, brothers, cousins, successors, variants, derivatives, and OSs inspired by it, and also AFAIK on DOS, classic Windows, and Windows NT, as well as OS/2). Dec 15, 2020 at 16:20

2 Answers 2

15

Sanity check: As far as I understand, the shell is the interface through which the user can interact with the OS, i.e.: run other processes.

Yes, but a "shell" is specifically a user interface, not a programming interface. Other programs are not required to interact with it – they can directly use the same system calls to create new processes.

So the command-line shell is on the same level as other programs, e.g. service managers, or graphical user interfaces (graphical shells).

Although the shell (e.g. Bash) is just another process.

Yes. On Unix-like systems it is a completely normal, unprivileged process.

Is there a way to run a process that will not be a child of a shell process?

From a user's perspective: yes, there are several ways.

  • Most shells have an exec keyword which causes the new program to replace the shell (retaining the same PID and parentship), which is probably not what you meant, but technically what you asked for.

  • Graphical desktop sessions will often start without invoking bash or any other shell, and this automatically applies to apps launched through the graphical menus. The app's parent will be whatever process was responsible for showing the menu (e.g. the window manager or the panel).

  • The currently popular systemd init system does not use a shell at all when starting services, so you can define a .service and start it – the service's parent will be init itself. It also has a feature allowing temporary services to be created on-the-fly using systemd-run, with the same results.

From a programmer's perspective, just use the fork() and execve() system calls to launch a new process. (There are OS-specific details, e.g. fork() might in fact be a wrapper for a different call, but it still works the same way.)

Indeed, even if the program wanted to invoke a shell, it would do so by creating a new child process and running /bin/sh using the same fork+exec. There is no special system call to run a shell. (The programmer could use e.g. system() when writing in C, or os.system() in Python, but those are still just convenience wrappers around fork/exec.)

Environment variables: In bash, there are several scripts that run when you spawn a shell, e.g. .bashrc, .bash_profile, etc. (depends on the type of shell - interactive vs non-interactive, login vs non-login). These scripts define the environment variables. If there's a way to run a process regardless to any shell, where do environment variables come from?

Well, sometimes they don't. (It's a real practical problem when trying to make graphical apps pick up environment customizations, depending on how that particular graphical environment starts.)

Overall, though, environment variables are not unique to CLI shells. Each process, no matter how it was started (including even the init process), receives an array of strings containing its command line – and an array of strings containing its environment variables. When launching a child process, it can either specify a different environment or allow a copy of its own environment to be inherited.

So when you log in, your shell already receives a few initial environment variables from its parent. Those startup scripts (bashrc, etc.) are just a convenient place for a user to customize the environment variables that the shell's child processes will then inherit.


Many parts of this answer also fully apply to Windows – although its graphical interface is a bit more complex, the CLI shells (cmd.exe and PowerShell) are still ordinary programs that aren't used at all in normal operation. The only major difference is that Windows has a single "CreateProcess" call instead of the Unix-style separate "fork + exec" calls.

0
4
  1. That is correct. Ultimately, the shell will perform the exec system call, which is available in all POSIX-compliant operating systems, and more generally in all Unix-like operating system, including Linux. Other operating systems have similar concepts. On Linux, the exec system call will ultimately call the execve function, which is provided by the kernel and does the actual job of loading the executable file and running it.

  2. Yes. Any process can call exec, and need not be a "shell". For example when you launch a program by clicking in a filesystem browser, the desktop software is the one performing the exec call, there is no shell. Note that the process becomes the child of the desktop software that launched it. All processes are the children of one other process, except the very first one, which is called init and has PID 1. It is responsible for setting up the operating system at start and launching all other processes, such as background services and desktop login. On Linux nowadays, systemd is often used as the init process, but there are other alternatives.

  3. There are several variants of exec (execl, execle, ...) that have various arguments in addition to the name of the program to be run. Ultimately, the execve system call takes a program name, a list of strings which are the command-line arguments, and a list of strings which are the environment variables. For example when launching software from a filesystem browser, the environment variables may be copied from the ones of the filesystem browser itself, possibly modified by the filesystem browser. This is entirely up to the programmers of the filesystem browser.

Some further reading:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.