shell faqs

Nearly everything you need to know about the shell

For a long period, shell is an important but vague concept in my head. I work with it everyday, but hardly what it really is. Normally, there are serveral typical use cases:

  1. through terminal, we enter some commands and see the output, like ls, cd, grep, less etc.
  2. we explicitly call the shell command: sh xxxx.sh or bash xx.sh
  3. we modify some special shell files like /etc/profile ~/.bashrc, ~/.bash_profile, ~/.profile, ~/.zshrc , such that the commands in these files will be automatically loaded when booting.

But, what is the difference between these two scenarios? What is the difference between sh command and bash command? What is the behavior if I am using zsh? What is the relation between shell and terminal?

In this article, we aim to give a conclusive and simple guide of shell. And finally give answers to above and more questions raised from my heart for a long time.

What is the shell?

Simply put, the shell is a program that takes commands from the keyboard and gives them to the operating system to perform. In the old days, it was the only user interface available on a Unix-like system such as Linux, which we usually called Command Line Interface(CLI).

For the second scenario, it is rather simple case since sh , bash, zsh , dash could simply be seen as an executable program to run the shell file. Different name just means different shell variant programs.

1
2
3
4
5
6
7
8
(base) Ξ ~ → ls -al /usr/bin/sh
lrwxrwxrwx 1 root root 4 Aug 5 2020 /usr/bin/sh -> dash
(base) Ξ ~ → ls -al /usr/bin/dash
-rwxr-xr-x 1 root root 129816 Jul 19 2019 /usr/bin/dash
(base) Ξ ~ → ls -al /usr/bin/bash
-rwxr-xr-x 1 root root 1183448 Jun 18 2020 /usr/bin/bash
(base) Ξ ~ → ls -al /usr/bin/zsh
-rwxr-xr-x 1 root root 878288 Feb 24 2020 /usr/bin/zsh

These shell variants do not differ in essence but in the additional functionalities they provide to the user. Nowadays, in most unix-like systems, bash and sh is usually bundled with the system and could be used out-of-the-box. zsh is widely recommended since it is a much more powerful shell which is compatible with a lot of plugins.

As for the first and third scenario, since the shell is the de facto interface between user and machine, when system boots, it needs to somehow specify a shell program to interact with the user. For most unix-like systems, the default shell program is bash . As a result, all commands typed in terminal is acutally executed by bash . And the special shells mentioned in the third scenario are also executed by bash. We could use chsh command to switch the default shell program, to zsh for instance. You could use echo $SHELL to check your configured default shell program.

1
2
(base) Ξ ~ → echo $SHELL
/usr/bin/zsh

Another non-negligible difference between these shells lies in the third scenario. As described in the beginning, when system boots, some special shell files will be automatically loaded and executed. Yet these files has a specific order to execute one by one. For example, the /etc/profile is a system-wise configuration, such that it will be first executed, while the ~/.bashrc is a user-specific and shell-specific configureation, which will be exuecuted later and activated when bash is selected as a default shell.

What is the terminal?

Usually we type our command in some terminal program. For example, in windows we use Windows Terminal. It’s a program called a terminal emulator. This is a program that opens a window and lets you interact with the shell. There are a bunch of different terminal emulators we can use. Some Linux distributions install several. These might include gnome-terminal, konsole, xterm, rxvt, kvt, nxterm, and eterm.

More about Second Scenario

It is worth to note that when we explicitly call sh xxx.sh or bash xxx.sh , it has nothing to do with the default shell we select. The behavior is as simple as calling a program to interpret the file, similar to python xxx.py .

Sometimes, we might add something like #!/bin/bash at the first line of a shell file. This will take effect when we convert the shell file as a executable file, usually by chmod a+x XXX.sh . Then ./XXX.sh will invoke the shell program specified by the first line.

Sometimes, we modify ~/.zshrc or ~/.bashrc and want it to take effect immediately. Then we tycially use source ~/.zshrc or . ~/.zshrc to activate it. As is explained in what-does-source-do, source or . is a bash built-in command that executes the content of the file passed as argument, in the current shell. The key difference is that

  • ./script or sh ./script runs the script as an executable file, launching a new shell to run it
  • source script reads and executes commands from filename in the current shell environment

So, if we change some variables with export command by the first means, it will not actually affect the variables in the current shell! For example, ./zshrc will not take any effect in the current shell:

1
2
#!/bin/bash
export HELLOWORLD="hello_world" ~ ~
1
2
3
4
5
6
7
8
9
(base) Ξ ~/playground → chmod a+x ./shell_demo.sh
(base) Ξ ~/playground → echo $HELLOWORLD

(base) Ξ ~/playground → ./shell_demo.sh
(base) Ξ ~/playground → echo $HELLOWORLD

(base) Ξ ~/playground → source shell_demo.sh
(base) Ξ ~/playground → echo $HELLOWORLD
hello_world

More about the third scenario

In this section, I would like to clarify the execution order of these special shells. Please see What is the difference between ~/.profile and ~/.bash_profile?, it lists the related shell files for each shell programs:

TENEX C shell

  • ~/.login When you login
  • ~/.logout When you logout
  • ~/.tcshrc same as ~./bashrc in bash

You can set variable $histfile as name of history file and variable $history as number of commands to keeping.

Z shell

Indeed it’s powerful shell and if you get free time, be sure migrate to it.

Except of other shell, Z shell has many configuration file and initialization files, just i write:

1
2
3
4
5
6
7
8
9
10
$ZDOTDIR/.zshenv
$ZDOTDIR/.zprofile
$ZDOTDIR/.zshrc
$ZDOTDIR/.zlogin
$ZDOTDIR/.zlogout
/tmp/zsh*
/etc/zshenv
/etc/zprofile
/etc/zshrc
/etc/zlogin

Note: if $ZDOTDIR unset, home set.

C shell

Note: TENEX C shell was forked from C shell. C shell supports by BSD. If you are familiar with C language programing, you should be comfortable since its syntax is similar.

1
2
3
~/.login
~/.cshrc
~/.logout

Note: csh is old. Use tcsh instead.

Korn Shell

  • ~/.profile
  • rc file: user defined
  • logout file: N/A

Bourne Again SHell (BASH)

It’s very very powerful shell and born under GNU project and forked by Bourne Shell.

1
2
3
4
5
~/.bash_login
~/.bash_logout
~/.bashrc
~/.bash_profile
~/.bash_history

When you login, bash runs ~/.bash_profile and ~/.bash_profile runs ~/.bashrc. Indeed ~/.bashrc isn’t bash initialization file, because bash doesn’t run it.

Bourne shell

It dead. Even when you use man sh, you see manual of dash. [Editor’s note: the bit about dash only applies to Debian and Debian-based distros like Ubuntu.]

Then I would specifically discuss the order of bash and zsh. Just read Zsh/Bash startup files loading order (.bashrc, .zshrc etc.), it has cleared everything to the ground.