1. Overview

In this tutorial, we’ll go over the differences between sh and Bash, and the features they offer. Finally, we’ll discuss which shell to use.

2. What Is a Shell?

A shell is a computer program that takes commands, interprets them, and passes them to the operating system to process. So, it’s an interface between the user and the operating system, through which a user can interact with the computer. To interact with the shell, we need a terminal emulator such as gnome-terminal, konsole, or st.

Most Linux-based operating systems come with at least one shell program. The shell program will probably be Dash, Bash, or both.

2.1. Current Shell

We can find out which shell are we currently using by simply reading the /etc/passwd file using grep:

$ grep $USER /etc/passwd
hey:x:1000:998::/home/hey:/bin/bash
  • The grep command expects a pattern and a file to read from
  • The $USER environment variable expands to the currently logged-in user
  • The /etc/passwd file stores user account information

By issuing the command, we can see that the default shell in use is bash. Therefore, when we use a terminal emulator, our commands will be interpreted by bash.

2.2. Installed Shells

We can list all the shells that are currently installed on our machine by reading the /etc/shell file:

$ cat /etc/shells
# Pathnames of valid login shells.
# See shells(5) for details.

/bin/sh
/bin/bash
/bin/dash

We can see that we have three shells installed on our machine. Technically, we have two shells, and we’ll see why in the next section.

3. sh

sh, also known as Bourne Shell, is a command programming language for UNIX-like systems, defined by the POSIX standards. sh can take input from either a keyboard or a file, commonly called a script file. On most Linux systems, it’s implemented by programs like the original Bourne Shell, dash, and ksh.

3.1. sh on POSIX Systems

POSIX is a family of standards defined by IEEE for vendors to make operating systems compatible. Thus, it helps us develop cross-platform software for multiple operating systems by following a set of guidelines. sh conforms to these standards.

On most Linux systems, sh is a symlink to the actual implementation of Bourne Shell. We can verify it through the following command:

$ file -h /bin/sh

As we can see, the /bin/sh is symbolically linked to dash, which is a POSIX compliant shell used by Debian-based distributions. In shell scripts, we can put the #!/bin/sh, as the first line, which in turn will be executed by dash:

#!/bin/sh

echo Hello, World!

The script will be executed by whatever the #!/bin/sh line points to, which in our case will be dash. On account of that, our script is portable to other POSIX compliant operating systems because it adheres to the POSIX standards.

3.2. Common Pitfall

Most shell scripts have #!/bin/sh as the first line, but we should note that /bin/sh might not be a symlink to a Bourne-compliant shell. Sometimes, script-writers assume that /bin/sh points to /bin/bash or /bin/dash, which doesn’t need to be.

For that reason, it’s a good practice to check the type of /bin/sh before writing and executing the script.

4. Bash

Like sh, Bash (Bourne Again Shell) is a command language processor and a shell. It’s the default login shell on most Linux distributions. Bash is a superset of sh, which means that Bash supports features of sh and provides more extensions on top of that. Though, most of the commands work similarly as in sh.

Since the release of Bash, it’s been the de facto shell for Linux operating systems.

4.1. Bash as a POSIX Compliant Shell

For a long time, /bin/sh was linked to /bin/bash. As time went on, bash developed more features and extensions, some of which didn’t adhere to the POSIX standards. Consequently, it was no longer an option on most Linux distros, and other POSIX compliant shells replaced it.

Nevertheless, we can still use Bash in the POSIX compliant mode, which we can invoke with the –posix flag with the bash command:

$ bash --posix

Alternatively, we can have a Bash script conform to the POSIX standard:

#!/bin/bash

set -o posix

echo Hello, World

The set command enables options within the script*,* which in this case will run the script in POSIX mode. Therefore, it makes the script portable for other operating systems such as FreeBSD and UNIX-like systems.

4.2. Features

Bash provides a lot of flexibility and syntax that looks a lot like those of modern programming languages. Some of the notable features introduced in Bash are:

  • Command-line completion can be used to quickly complete a command using the key
  • Command history through which we can quickly search for commands previously executed by using the arrow key or
  • Arithmetic evaluation without having to use external programs
  • Associative arrays, which enables us to create an array with string indices
  • Keyboard shortcuts for command-line editing
  • Customizability enables us to modify the default presentation offered by Bash

4.3. Writing a Bash Script

Bash is also capable of reading commands from a file. We specify the #!/bin/bash Shebang as the first line, followed by our script:

#!/bin/bash

# Finds out whether a number is even or odd

read -p "Enter a number: " number

if [ `expr $number % 2` -eq 0 ]; then
    echo "${number} is even"
else
    echo "${number} is odd"
fi

Save the script file and make it executable:

$ chmod +x is_even.sh
$ ./is_even
Enter a number: 13
13 is odd

This script will run on most Linux distributions, but if we run the same script on FreeBSD, we might run into problems.

5. Which One to Use?

Both shells are useful, and we can leverage them in different situations. For instance, we can use sh if we want our script to be compatible across multiple systems. On the other hand, we might choose Bash because it provides a fluid syntax and more compelling features.

Nonetheless, we can use Bash and run it in pure POSIX mode if we are paranoid about portability and compatibility. Aside from that, if we write a sh script, it will most likely run on Bash without modification because Bash is backward-compatible with sh.

6. Conclusion

In this article, we looked at an over of the shell program and how we can find the current and installed shells on our system. Then, we went through the differences between Bash and sh alongside their features and their conformation with POSIX.