What is a shell?
A [Li|U]nix shell is the command-line interface between the user and the system. It is used to perform some action, specifically, typing commands and displaying output, requested by the user.
Introduction to Bash
Bash is known as the Bourne-again shell, written by Brian Fox, and is a play on the name of the previously named Bourne shell (/bin/sh) written by Steve Bourne. 
Command-line Editing Modes
Over time, as one progresses with using the shell, it will become necessary to execute
commands that may contain many arguments or have output piped to other commands. Beyond
simple commands such as
ls, it can be tedious should one need to re-type,
or, in most cases, edit, a given command. Luckily,
bash provides a facility to make
this scenario easier: the command-line editing mode.
The command-line editing mode emulates the movement functions of two common text editors,
vi. In the case of the shell, the cursor's movement is being controlled.
bash operates in
Example Edit Commands
The following commands are very common while using the
Ctrl-b: Move backward by one character
Ctrl-f: Move forward by one character
Ctrl-a: Move to the beginning of the line
Ctrl-e: Move to the end of the line
Ctrl-k: Delete from the cursor forward
Ctrl-u: Delete from the cursor backward
Ctrl-r: Search the command history
The following commands are very common while using the
h: Move backward by one character
l: Move forward by one character
0: Move to the beginning of the line
$: Move to the end of the line
d$: Delete from the cursor to the end of the line
d0: Delete from the cursor the beginning of the line
:history s: Search the command history
Setting the Mode
One can manually set the desired mode using the below commands.
set -o emacs
set -o vi
See :doc:`text_editing_101` for details on appropriate edit commands to use on the command line.
Environment variables are used to define values for often-used attributes of a
user's shell. In total, these variables define the user's environment. Some
environment variables provide a simple value describing some basic attribute,
such the user's current directory (
$PWD). Others define the behavior of a
command, such as whether or not the
history command should log repeated
commands individually or log the repeated command once (
The most common, or most recognized, environment variable is the
variable. It defines the set of directories that the shell can search to find a
command. Without an explicit path provided when calling a command (i.e.
the shell will search the directories listed in the
$PATH variable until it
finds the command. If the command is not found in any of the defined directories
$PATH, the shell will produce an error explaining as much.
$ foobar -V -bash: foobar: command not found
To view the contents of the
$PATH variable, use
echo to print the variable's value:
$ echo $PATH /usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
The order of the directories in the
$PATH variable, from left to right, is
important; when searching directories for a command, the shell will stop looking
after it finds its first match.
In other words, using our example
$PATH variable above, if there is a
ps that exists in
/usr/local/bin that is preferred (by the sysadmin)
over the version that exists in
/bin, the shell will still execute
due to the precedence of the directories defined in the
To list all of the shell's environment variables, use the
$ env HOSTNAME=foobar SHELL=/bin/bash TERM=xterm HISTSIZE=1000 USER=root PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/bin MAIL=/var/spool/mail/root PWD=/root/curriculum PS1=[\[\e[33;1m\]\t \[\e[31;1m\]\u\[\e[0m\]@\[\e[31;1m\]\h\[\e[0m\] \W\[\e[0m\]]# HISTCONTROL=ignoredups SHLVL=1 SUDO_COMMAND=/bin/bash HOME=/root HISTTIMEFORMAT=[%Y-%m-%d %H:%M:%S] OLDPWD=/tmp
Shell profiles are used to define a user's environment. In cases where an environment variable needs to be set or a script needs to be run at login, a profile can be used to ensure this happens consistently and automatically. Anything that can be run in a standalone shell script can be placed in a profile.
There are two types of profiles:
- Global profile (
- User profile (
This is the global profile. Any environment variable set in this file applies to all users. Any script called from this file is executed for all users.
This is the user profile. Any environment variable set in this file applies to the user only. Any script called from this file is executed for the user only.
NOTE: It is possible to override settings from
is executed after
Special Environment Variables
Certain variables exist that provide useful information about what is happening in the environment. For example, it may be necessary to know the ID of a running process or the exit status of an executed command.
To determine the process ID (PID) of the current shell, first run
ps to find the PID, then run
to confirm the PID.
$ ps -efl | grep bash 502 20440 20439 0 10:25PM ttys001 0:00.01 -bash 4006 31 0 2433436 1228 - S 0 502 20447 20440 0 10:29PM ttys001 0:00.00 grep bash 4006 31 0 2432768 620 - R+ 0 $ echo $$ 20440
Background Process ID:
Occasionally, commands will need to be executed in the background (via the
& operator). The PID of that process
can be found using the
$! variable. For example, call
sleep for 30 seconds and place it in the background.
echo $! to see the PID. Alternatively, call
ps to confirm the PID.
$ sleep 30 &  20450 $ echo $! 20450 $ ps -efl | grep sleep 502 20450 20440 0 10:33PM ttys001 0:00.00 sleep 30 4006 31 0 2432748 496 - S 0
When a command is executed, it always has an exit status. That status defines whether or not the command was successful. For success, the exit status is 0. Non-zero values denote failure. Many commands provide multiple exit codes to help define what the reason for failure was. This helps the user troubleshoot any problems.
As an example, try to list a known file within a user's home directory, then list a file that is known not to exist.
After each command, execute
echo $? to see the exit status.
$ ls .bash_profile .bash_profile $ echo $? 0 $ ls foobar ls: foobar: No such file or directory $ echo $? 1
The history is a handy facility within
bash; it stores all of the commands that the user has executed.
To see the history, simply type
history and all of the stored commands will be displayed to the terminal.
cat ~/.bash_history to see all stored commands.
A benefit of storing command history is that the commands can be easily recalled. To execute the last command,
$ ls file1 file2 dir1 $ !! ls file1 file2 dir1
Note that the last command is echoed just above the output of that command.
To execute the nth command in history, run
n is the line number of the command as found in the
$ history | less 1 ls -la 2 ls -F 3 pwd $ !2 ls -F file1 file2 dir1/
Finally, one can search the history by typing
Ctrl-r followed by a string to match a command:
$ (reverse-i-search)`ls': ls -F
To execute the command (if a match is found), simply type Enter.
From time to time, it may be necessary to manage commands running in the background. These are typically referred to as jobs.
A command can be placed in the background via the
& operator. Use the
jobs command to see the job in the background.
To bring it back to the foreground, run
[23:24:22 ~]$ sleep 30 &  20969 [23:24:26 ~]$ jobs + Running sleep 30 & [23:24:29 ~]$ fg sleep 30 [23:24:56 ~]$
While in the foreground, the job can be suspended via
Ctrl-z and sent to the background once more using
[23:24:56 ~]$ sleep 30 &  21078 [23:28:25 ~]$ jobs + Running sleep 30 & [23:28:27 ~]$ fg sleep 30 ^Z + Stopped sleep 30 [23:28:33 ~]$ bg + sleep 30 & [23:28:37 ~]$ jobs + Running sleep 30 & [23:29:39 ~ ]$ jobs + Done sleep 30
It is possible to have multiple jobs running in the background at the same time. Use the
jobs command to track them
via their job ID, noted between the square brackets after sending a job to the background. Knowing the job ID is helpful in
the event that the job needs to be pulled into the foreground (via
fg) or if the job needs to be killed:
[23:36:01 ~]$ sleep 120 &  21086 [23:36:16 ~]$ sleep 240 &  21087 [23:36:20 ~]$ jobs - Running sleep 120 & + Running sleep 240 & [23:36:21 ~]$ fg %1 sleep 120 ^C [23:36:33 ~]$ jobs + Running sleep 240 & [23:36:35 ~]$ kill %2 [23:36:39 ~]$ jobs + Terminated: 15 sleep 240
NOTE: When manipulating jobs with any command, the jobs are described by their ID using the
n is the job ID.
|||C Programming by Al Stevens, Dr. Dobb's Journal, July 1, 2001|