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
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.
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 thenlk$ 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 &  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.
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
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!
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,
|man command||Show the manual for the command.|
|ls -ls||Directory listing in long format, giving file size in blocks.|
|ls -lst||Directory listing sorted by time of file modification, most recent first.|
|ls -lsa||Directory listing showing all files, including files with names starting with a period.|
|cp file1 file2||Copy file1 to file2. file2, if exists, is lost without warning.|
|mv file1 file2||Move (rename) file1 to file2. file2, if exists, is lost without warning.|
|rm file ...||Remove (delete) file(s).|
|rm -r file ...||Remove files. If any file is a directory, remove all files under it and then itself.|
|cat file ...||Concatenate file(s) and print on the standard output.|
|wc file||Count number of lines, words and characters in file|
|grep pattern file||Find lines containing strings that match pattern in file|
|sort file||Sort the lines in file|
|head file||Print the first 10 lines of file|
|tail file||Print the last 10 lines of file|
|diff file1 file2||Find the differences between file1 and file2|
|cmp file1 file2||Compare file1 and file2. Print location of the first difference.|
|vi file||Open file in the vi text editor|