An Introduction to Shell in Linux

  • Post author:
  • Post last modified:August 25, 2023
  • Reading time:13 mins read

1.0 SHELL

A shell provides a user interface to a computer system. There are two types of shells, the command line interface (CLI) and the graphical user interface (GUI). In this tutorial, we describe the command line interface shell only and refer to it simply as shell.

A CLI shell is a programmable command interpreter software. As a CLI shell provides a language for interacting with a computer's operating system, it provides a powerful, precise and flexible way of running commands. One of the earliest CLI shells is the Bourne shell, named sh, developed by Stephen Bourne and released in 1977 along with the Seventh Edition Unix. The C shell, named csh earlier, and later on, with improvements, as tcsh, was created by Bill Joy in 1978. The Korn shell was developed by David Korn and released in 1983. bash is the Bourne-again shell and was developed by Brian Fox for the GNU project and was first released in 1989. bash is the default shell under Linux.

2.0 Starting bash

In case of CLI shells, bash is started after the successful login initiated via the getty program. In case of GUI shells, a CLI shell is provided as a terminal emulator program, like the GNOME terminal. After clicking on the gnone-terminal icon, the gnome-terminal process is started, which runs the bash process and provides the bash CLI shell.

bash running inside gnome-terminal

Fig.1 bash running inside gnome-terminal

3.0 Executing commands

With bash running, we can execute commands in it. Some commands are built in the shell. It executes these directly. Most commands, however, are in the form of an executable file. For these, bash forks (creates) a child process and then execs (executes) the program for that command in the newly created child process. For example,

$ #print the present working directory
$ pwd
/home/user1
$ date
Sun Dec 28 07:21:51 IST 2014
$ # list the files in pwd
$ ls -ls
total 1740
   4 drwxr-xr-x  2 user1 user1    4096 Dec 24 20:25 Audio
   4 drwxr-xr-x  2 user1 user1    4096 Aug 31 13:58 Desktop
   4 drwxr-xr-x  3 user1 user1    4096 Oct 14  2013 Documents
   ...
   4 drwxr-xr-x  2 user1 user1    4096 Oct 29  2013 Videos
   4 drwxr-xr-x 20 user1 user1    4096 Nov  5 21:20 www
$ # list all files with name having s as first character and rest any character(s)
$ ls -ls s*
4 -rw-rw-r-- 1 user1 user1  9 Dec 28 16:51 silk
4 -rw-rw-r-- 1 user1  user1  84 Dec 28 13:47 sorted-list
$ # list all files with names having s as first character, then any character and then lk
$ ls -ls s?lk
4 -rw-rw-r-- 1 user1 user1 9 Dec 28 16:51 silk

In bash command syntax, * and ? are special characters used in matching file names. The special character * means any string of characters. So ls -ls * lists all files. The special character ? means any single character.

Normally, shell waits for a command to complete, before it displays the prompt for the next command. However, you can run commands in background by typing ampersand (&) at the end of a command and shell displays the command prompt immediately. In this case, the command executes in the background.

$ ./long-running-command &
[1] 5544

You might have noticed that we typed ./long-running-command as the command name above. The ./ means the present working directory. It means that the shell should look for the long-running-command in the present working directory. This brings us to the concept of the PATH environment variable. We can see the value of PATH,

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

The PATH environment variable contains a list of directories separated by the colon delimiter. When we want to execute a file, we can type a full file path name like /usr/bin/gcc or ./long-running-command. It is exact and completely unambiguous. The shell either finds the executable file and executes it or, if it is unable to find the file, it gives an error. However, if we just type the executable file name like long-running-command, the shell has to locate the file. The shell looks for the file in each of the directories listed in the PATH variable. If it finds the file, it executes, otherwise it gives an error. The shell looks in the directories in the order they are listed in the PATH; so in the example PATH mentioned above, if there is an executable file foo in /usr/sbin and /sbin directories, /usr/sbin/foo would get executed. There is a command which, which, given the file name, gives the complete path name of the file that would be executed. For example,

$ which gcc
/usr/bin/gcc
$ which cc
/usr/bin/cc
$ which lcc   # does not exist in any of the directories in the PATH
$

4.0 Standard Input, Standard Output and Standard Error Files

Each Linux process has standard input, standard out and standard error file descriptors numbered 0, 1 and 2 respectively. The default standard input is the keyboard. The standard output and standard error files are, by default, the display. We can redirect standard input and standard output streams to any other file by using the < and > operators respectively. The standard error can be redirected by writing 2> filename. For example,

$ echo "Hello World!"
Hello World!
$ echo "Hello World!" >hello
$ cat hello
Hello World!
$ cat <hello
Hello World!
$ cat Hello 2>err
$ cat err
cat: Hello: No such file or directory 

For appending to a file, the >> operator is to be used. And, if you want to trash some output, just redirect it to /dev/null.

$ echo "Hello, the brave new world!" >>hello
$ cat hello
Hello World!
Hello, the brave new world!
$ # try to print Hello (non-existent), and trash the error message, if any
$ cat Hello 2>/dev/null      # no error message

Suppose you want the standard output and standard error to go to the same file, we can try something like this,

$ cat hello Hello >new-hello 2>&1
$ cat new-hello
Hello World!
Hello, the brave new world!
cat: Hello: No such file or directory

The syntax 2>&1 means, redirect 2 (standard error) to the same place (&) as 1 (standard output).

And, if we wish to append the standard output and standard error instead of plain redirecting,

$ cat new-hello hello Yello >>valo 2>&1
$ cat valo
Hello World!
Hello, the brave new world!
cat: Hello: No such file or directory
Hello World!
Hello, the brave new world!
cat: Yello: No such file or directory

While giving standard input from the keyboard, Control-D signals the end of input (file). For example,

$ cat > new-file
Hello World!
Hello, the brave new world!
'Tis the season.
<Ctrl-D>
$ cat new-file
Hello World!
Hello, the brave new world!
'Tis the season.

Instead of Control-D, we can use the syntax, cat <<delimiter and then put delimiter in a new line at the end of input. All text after the cat command line and up to the delimiter is taken as input.

$ cat <<EOF >file1
> Hello World!
> Hello, the great new world!
> 'Tis the season.
> EOF
$ cat file1
Hello World!
Hello, the great new world!
'Tis the season.

5.0 Pipes

The redirection operators described above redirect a stream to a file. Suppose, we wish to redirect the output of one process to another? A pipe is represented by the vertical bar character (|) and denotes a pipeline between two processes. The standard output of the process on the left of pipe becomes the standard input of the process on the right. It is possible to connect multiple processes downstream on a pipeline. For example,

$ ls
Desktop    Downloads         Music     Public     Videos
Documents  examples.desktop  Pictures  Templates
$ ls | sort
Desktop
Documents
Downloads
examples.desktop
Music
Pictures
Public
Templates
Videos
$ ls | sort | wc
      9       9      84

The shell provides redirection by switching the file descriptors of a device file with that of redirected file. Also, the kernel provides the endpoints of a pipe as file descriptors. So the shell can switch the standard input or output file descriptor of a process with that of a pipe endpoint.

6.0 tee command

Suppose we wish to have a pipeline of commands and also tap the data flowing through the pipeline at some point. We can put a tee command at the point we wish to tap the data and capture it in a file. For example,

$ ls | sort | tee sorted-list | wc
      9       9      84
$ cat sorted-list
Desktop
Documents
Downloads
examples.desktop
Music
Pictures
Public
Templates
Videos

7.0 History

bash keeps a history of past commands. You can see the history of past commands and execute one of those commands. For example,

$ history   # show history of past commands
...
 1996  cd tmp
 1997  vi bash.txt 
 1998  cd tmp
 1999  cd ~/scripts
 2000  ls
 ...
$ history 10  # show the last 10 commands
 1989  vi hello
 1990  ./hello one two three four five six seven eight nine ten eleven twelve
 1991  fortune
 ...
$ !1991 # execute command 1991
fortune
It was all so different before everything changed.
$ ls     # list files
   ...
$ !!      # execute the last command
ls
   ...
$ !-2    # execute the command before the last command
fortune
If you think last Tuesday was a drag, wait till you see what happens tomorrow!

8.0 Invocation

If bash is invoked as a login shell, it executes /etc/profile, ~/.bash_profile, ~/.bash_login and ~/.profile at login. At logout, it executes ~/.bash_logout. If bash is invoked as a non-login interactive shell, say as by the gnome-terminal process, it executes /etc/bash.bashrc and ~/.bashrc at start. These files are used for setting the environment variables like PATH and the command prompts, PS1 and PS2. The files in the etc directory can be used for setting meaningful defaults for all users, while the files in the HOME directory can be used for customizing these as per individual needs.

9.0 Commonly Used Commands

Some of the commonly used commands are,

Commonly used commands in shell
CommandDescription
man commandShow the manual for the command.
ls -lsDirectory listing in long format, giving file size in blocks.
ls -lstDirectory listing sorted by time of file modification, most recent first.
ls -lsaDirectory listing showing all files, including files with names starting with a period.
cp file1 file2Copy file1 to file2. file2, if exists, is lost without warning.
mv file1 file2Move (rename) file1 to file2. file2, if exists, is lost without warning.
rm fileRemove (delete) file(s).
rm -r fileRemove files. If any file is a directory, remove all files under it and then itself.
cat fileConcatenate file(s) and print on the standard output.
wc fileCount number of lines, words and characters in file
grep pattern fileFind lines containing strings that match pattern in file
sort fileSort the lines in file
head filePrint the first 10 lines of file
tail filePrint the last 10 lines of file
diff file1 file2Find the differences between file1 and file2
cmp file1 file2Compare file1 and file2. Print location of the first difference.
vi fileOpen file in the vi text editor

10.0 See also

Share

Karunesh Johri

Software developer, working with C and Linux.
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments