[<--] [Cover] [Table of Contents] [Concept Index] [Program Index] [-->]
Google
 
Web dsl.org


The Shell

The subject of this chapter is the shell, the program that reads your command input and runs the specified commands. The shell environment is the most fundamental way to interact with the system -- you are said to be "in" a shell from the very moment you've successfully logged in to the system.

The `$' character preceding the cursor is called the shell prompt; it tells you that the system is ready and waiting for input. On Debian systems, the default shell prompt also includes the name of the current directory (see Files and Directories). A tilde character (`~') denotes your home directory, which is where you'll find yourself when you log in.

For example, a typical user's shell prompt might look like this:



~ $ _

If your shell prompt shows a number sign (`#') instead of a `$', this means that you're logged in with the superuser, or root, account. Beware: the root account has complete control over the system; one wrong keystroke and you might accidentally break it something awful. You need to have a different user account for yourself, and use that account for your regular use (see Making a User Account).

Every Linux system has at least one shell program, and most have several. We'll cover bash, which is the standard shell on most Linux systems. (Its name stands for "Bourne again shell"---a pun on the name of Steve Bourne, who was author of the traditional Unix shell, the Bourne shell.)

NOTE: See Info file `bashref.info', node `Top', for more information on using bash.

Keys for Command Line Editing

In Running a Command, you learned how to run commands by typing them in at the shell prompt. The text you type at a shell prompt is called the command line (it's also called the input line).

The following table describes the keystrokes used for typing command lines.
KEYSTROKES DESCRIPTION
text Insert text at the point where the cursor is at; if there is text to the right of the cursor, it is shifted over to the right.
[BKSP] Delete the character to the left of the cursor.
[DEL] Delete the character the cursor is underneath.
[RET] Send the command line to bash for execution (in other words, it runs the command typed at the shell prompt). You don't have to be at the far right end of the command line to type [RET]; you can type it when the cursor is anywhere on the command line.
C-a Move the cursor to the beginning of the input line.
C-d Same as [DEL] (this is the Emacs equivalent).
C-e Move the cursor to the end of the input line.
C-k Kill, or "cut," all text on the input line, from the character the cursor is underneath to the end of the line.
C-l Clear the terminal screen.
C-u Kill the entire input line.
C-y Yank, or "paste," the text that was last killed. Text is inserted at the point where the cursor is.
C-_ Undo the last thing typed on this command line.
[] Move the cursor to the left one character.
[] Move the cursor to the right one character.
[] and [] Cycle through the command history (see Command History).
NOTE: These keyboard commands are the same as those used by the Emacs editor (see Emacs). Many other Emacs keyboard commands also work on the command line (see Basic Emacs Editing Keys). And, for Vi aficionados, it is possible to configure bash to recognize Vi-style bindings instead. The following sections describe some important features of command line editing, such as quoting special characters and strings, letting the shell complete your typing, re-running commands, and running multiple commands. See Info file `bashref.info', node `Command Line Editing' for more information on bash's command line editing features.

Passing Special Characters to Commands

Some characters are reserved and have special meaning to the shell on their own. Before you can pass one of these characters to a command, you must quote it by enclosing the entire argument in single quotes (`'').

For example, here's how to pass `Please Stop!' to a command:

'Please Stop!'

When the argument you want to pass has one or more single quote characters in it, enclose it in double quotes, like so:

"Please Don't Stop!"

To pass special characters as a string, give them as:

$'string'

where string is the string of characters to be passed. Special backslash escape sequences for certain characters are commonly included in a string, as listed in the following table.
ESCAPE SEQUENCE DESCRIPTION
\a Alert (rings the system bell).
\b Backspace.
\e Escape.
\f Form feed.
\n Newline.
\r Carriage return.
\t Horizontal tab.
\v Vertical tab.
\\ Backslash.
\NNN Character whose ASCII code is NNN in octal (base 8).
To demonstrate the passing of special character sequences to tool, the following examples will use the figlet tool, which displays the text you give as an argument in a "font" made up of text characters (see Horizontal Text Fonts).

Letting the Shell Complete What You Type

Completion is where bash does its best to finish your typing. To use it, press [TAB] on the input line and the shell will complete the word to the left of the cursor to the best of its ability. Completion is one of those things that, once you begin to use it, you will wonder how you ever managed to get by without.

Completion works on both file names and command names, depending on the context of the cursor when you type [TAB].

For example, suppose you want to specify, as an argument to the ls command, the `/usr/lib/emacs/20.4/i386-debian-linux-gnu/' directory -- that's a lot to type. So instead of typing out the whole directory name, you can type [TAB] to complete it for you. Notice how our first attempt, typing only the letter `e' in `/e', brings up a series of files -- while the second attempt, typing `em', further refines our search:

$ ls /usr/lib/e[TAB]
elm-me+    emacs      emacsen-common  entity-map    expect5.30
$ ls /usr/lib/em[TAB]

At this point, the system beeps(12) and the shell completes the word `emacs', since all options in this directory beginning with the letters `em' complete to at least that word. Press /[TAB] to access this word and go on, and the shell completes the subdirectory `20.4' since that is the only file or directory in the `emacs' subdirectory:

$ ls /usr/lib/emacs/[TAB]20.4/

Press [TAB] again to have the shell complete the only subdirectory in `20.4':

$ ls /usr/lib/emacs/20.4/[TAB]i386-debian-linux-gnu/

NOTE: Many applications also support command and/or file name completion; the most famous example of this is the Emacs text editor (see Emacs).

Repeating the Last Command You Typed

Type [] to put the last command you typed back on the input line. You can then type [RET] to run the command again, or you can edit the command first.

The [] key moves the last command you typed back to the input line, and [RET] executes it.

By typing [] more than once, you can go back to earlier commands you've typed; this is a function of your command history, which is explained in full in Command History.

Additionally, you can use the bash reverse-incremental search feature, C-r, to search, in reverse, through your command history. You'll find this useful if you remember typing a command line with `foo' in it recently, and you wish to repeat the command without having to retype it. Type C-r followed by the text foo, and the last command you typed containing `foo' appears on the input line.

Like the Emacs command of the same name (see Searching Incrementally in Emacs), this is called an incremental search because it builds the search string in character increments as you type. Typing the string `cat' will first search for (and display) the last input line containing a `c', then `ca', and finally `cat', as you type the individual characters of the search string. Typing C-r again retrieves the next previous command line that has a match for the search string.

When a command is displayed on the input line, type [RET] to run it. You can also edit the command line as usual.

Running a List of Commands

To run more than one command on the input line, type each command in the order you want them to run, separating each command from the next with a semicolon (`;'). You'll sometimes find this useful when you want to run several non-interactive commands in sequence.

Redirecting Input and Output

The shell moves text in designated "streams." The standard output is where the shell streams the text output of commands -- the screen on your terminal, by default. The standard input, typically the keyboard, is where you input data for commands. When a command reads the standard input, it usually keeps reading text until you type C-d on a new line by itself.

When a command runs and exits with an error, the error message is usually output to your screen, but as a separate stream called the standard error.

You redirect these streams -- to a file, or even another command -- with redirection. The following sections describe the shell redirection operators that you can use to redirect standard input and output.

Redirecting Input to a File

To redirect standard input to a file, use the `<' operator. To do so, follow a command with < and the name of the file it should take input from. For example, instead of giving a list of keywords as arguments to apropos (see Finding the Right Tool for the Job), you can redirect standard input to a file containing a list of keywords to use.

Redirecting Output to a File

Use the `>' operator to redirect standard output to a file. To use it, follow a command with > and the name of the file the output should be written to.

If you redirect standard output to an existing file, it will overwrite the file, unless you use the `>>' operator to append the standard output to the contents of the existing file.

Redirecting Error Messages to a File

To redirect the standard error stream to a file, use the `>' operator preceded by a `2'. Follow a command with 2> and the name of the file the error stream should be written to.

As with the standard output, use the `>>' operator instead of `>' to append the standard error to the contents of an existing file.

To redirect both standard output and standard error to the same file, use `&>' instead.

Redirecting Output to Another Command's Input

Piping is when you connect the standard output of one command to the standard input of another. You do this by specifying the two commands in order, separated by a vertical bar character, `|' (sometimes called a "pipe"). Commands built in this fashion are called pipelines.

For example, it's often useful to pipe commands that display a lot of text output to less, a tool for perusing text (see Perusing Text).

This redirects the standard output of the command apropos bash shell shells to the standard input of the command less, which displays it on the screen.

Managing Jobs

The processes you have running in a particular shell are called your jobs. You can have more than one job running from a shell at once, but only one job can be active at the terminal, reading standard input and writing standard output. This job is the foreground job, while any other jobs are said to be running in the background.

The shell assigns each job a unique job number. Use the job number as an argument to specify the job to commands. Do this by giving the job number preceded by a `%' character.

To find the job number of a job you have running, list your jobs (see Listing Your Jobs).

The following sections describe the various commands for managing jobs.

Suspending a Job

Type C-z to suspend or stop the foreground job -- useful for when you want to do something else in the shell and return to the current job later. The job stops until you either bring it back to the foreground or make it run in the background (see Putting a Job in the Foreground and see Putting a Job in the Background).

For example, if you are reading a document in info, typing C-z will suspend the info program and return you to a shell prompt where you can do something else (see Using the GNU Info System). The shell outputs a line giving the job number (in brackets) of the suspended job, the text `Stopped' to indicate that the job has stopped, and the command line itself, as shown here:

[1]+  Stopped                 info -f cookbook.info

In this example, the job number is 1 and the command that has stopped is `info -f cookbook.info'. The `+' character next to the job number indicates that this is the most recent job.

If you have any stopped jobs when you log out, the shell will tell you this instead of logging you out:



$ logout [RET] There are stopped jobs. $

At this point you can list your jobs (see Listing Your Jobs), stop any jobs you have running (see Stopping a Job), and then log out.

Putting a Job in the Background

New jobs run in the foreground unless you specify otherwise. To run a job in the background, end the input line with an ampersand (`&'). This is useful for running non-interactive programs that perform a lot of calculations.

The shell outputs the job number (in this case, 1) and process ID (in this case, 6575), and then returns to a shell prompt. When the background job finishes, the shell will list the job number, the command, and the text `Done', indicating that the job has completed successfully:

[1]+  Done                    apropos shell >shell-commands

To move a job from the foreground to the background, first suspend it (see Suspending a Job) and then type bg (for "background").

If you have suspended multiple jobs, specify the job to be put in the background by giving its job number as an argument.

NOTE: Running a job in the background is sometimes called "backgrounding" or "amping off" a job.

Putting a Job in the Foreground

Type fg to move a background job to the foreground. By default, fg works on the most recent background job.

To move a specific job to the foreground when you have multiple jobs in the background, specify the job number as an option to fg.

Listing Your Jobs

To list the jobs running in the current shell, type jobs.

This example shows two jobs---apropos shell > shell-commands and apropos bash > bash-commands. The `+' character next to a job number indicates that it's the most recent job, and the `-' character indicates that it's the job previous to the most recent job. If you have no current jobs, jobs returns nothing.

To list all of the processes you have running on the system, use ps instead of jobs---see Listing System Activity.

Stopping a Job

Typing C-c interrupts the foreground job before it completes, exiting the program.

Use kill to interrupt ("kill") a background job, specifying the job number as an argument.

Command History

Your command history is the sequential list of commands you have typed, in the current or previous shell sessions. The commands in this history list are called events.

By default, bash remembers the last 500 events, but this number is configurable (see Customizing Future Shells).

Your command history is stored in a text file in your home directory called `.bash_history'; you can view this file or edit it like you would any other text file.

Two very useful things that having a command history lets you do is to repeat the last command you typed, and (as explained earlier in this chapter) to do an incremental backwards search through your history.

The following sections explain how to view your history and specify events from it on the command line. See Info file `bashref.info', node `Bash History Facilities', for more information on command history.

Viewing Your Command History

Use history to view your command history.

This command shows the contents of your command history file, listing one command per line prefaced by its event number. Use an event number to specify that event in your history (see Specifying a Command from Your History).

If your history is a long one, this list will scroll off the screen, in which case you may want to pipe the output to less in order to peruse it. It's also common to search for a past command by piping the output to grep (see Redirecting Output to Another Command's Input and Searching for a Word or Phrase).

This command will show the events from your history containing the text `apropos'. (The last line of output is the command you just typed.)

Specifying a Command from Your History

You can specify a past event from your history on the input line, in order to run it again.

The simplest way to specify a history event is to use the up and down arrow keys at the shell prompt to browse your history. The up arrow key ([]) takes you back through past events, and the down arrow key ([]) moves you forward into recent history. When a history event is on the input line, you can edit it as normal, and type [RET] to run it as a command; it will then become the newest event in your history.

To run a history event by its event number, enter an exclamation point (`!', sometimes called "bang") followed by the event number. (Get the event number by viewing your history; see Viewing Your Command History).

Recording a Shell Session

Use script to create a typescript, or "capture log," of a shell session -- it writes a verbatim copy of your session to a file, including commands you type and their output. The first and last lines of the file show the beginning and ending time and date of the capture session. To stop recording the typescript, type exit at a shell prompt. By default, typescripts are saved to a file called `typescript' in the current directory; specify the file name to use as an argument.

In this example, the typescript records a shell session consisting of two commands (hostname and apropos) to a file called `log.19990817'. The typescript looks like this:

Script started on Tue May 25 14:21:52 1999
$ hostname
erie
$ apropos bash > bash.commands
$ exit
exit

Script done on Tue May 25 14:22:30 1999

NOTE: It's possible, but usually not desirable, to run script from within another script session. This usually happens when you've forgotten that you are running it, and you run it again inside the current typescript, even multiple times -- as a result, you may end up with multiple sessions "nested" inside each other like a set of Russian dolls.

Customizing Your Shell

The following sections describe the most common ways to customize the shell -- including changing the text of the shell prompt and creating aliases for other commands. These customizations will apply to the rest of your current shell session, unless you change them again. Eventually, you will want to make them work all the time, like whenever you log in or start a new shell -- and how to do this is discussed below.

Changing the Shell Prompt

A shell variable is a symbol that stores a text string, and is referenced by a unique name. bash keeps one special variable, named PS1, for the text of the shell prompt. To change the text of the shell prompt, you need to change the contents of the PS1 variable.

To change a variable's contents, type its name followed by an equal sign (`=') character and the string that should replace the variable's existing contents.

Since the replacement text has spaces in it, we've quoted it (see Passing Special Characters to Commands).

You can put special characters in the prompt variable in order to output special text. For example, the characters `\w' in the value of PS1 will list the current working directory at that place in the shell prompt text.

The following table lists some special characters and their text output at the shell prompt.
SPECIAL CHARACTER TEXT OUTPUT
\a Inserts a C-g character, which makes the internal speaker beep. (It "rings the system bell"; C-g is sometimes called the bell character.)
\d The current date.
\h The hostname of the system.
\n A newline character.
\t The current system time, in 24-hour format.
\@ The current system time, in 12-hour a.m./p.m. format.
\w The current working directory.
\u Your username.
\! The history number of this command.
You can combine any number of these special characters with regular characters when creating a value for PS1.

Making a Command Alias

Use alias to assign an alias, a name that represents another command or commands. Aliases are useful for creating short command names for lengthy and frequently used commands.

This command makes `bye' an alias for `exit' in the current shell, so typing bye would then run exit.

You can also include options and arguments in an alias.

This command makes `ap' an alias for `apropos shell bash shells' in the current shell, so typing ap would run apropos shell bash shells.

Adding to Your Path

To add or remove a directory in your path, use a text editor to change the shell variable `PATH' in the `.bashrc' file in your home directory (see Text Editing).

For example, suppose the line that defines the `PATH' variable in your `.bashrc' file looks like this:

PATH="/usr/bin:/bin:/usr/bin/X11:/usr/games"

You can add the directory `/home/nancy/bin' to this path, by editing this line like so:

PATH="/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/nancy/bin"

NOTE: See Files and Directories for a complete description of directories and the path.

Customizing Future Shells

There are a number of configuration startup files in your home directory that you can edit to make your configurations permanent. You can also edit these files to specify commands to be run whenever you first log in, log out, or start a new shell. These configuration files are text files that can be edited with any text editor (see Text Editing).

When you log in, bash first checks to see if the file `/etc/profile' exists, and if so, it executes the commands in this file. This is a generic, system-wide startup file that is run for all users; only the system administrator can add or delete commands to this file.

Next, bash reads and executes the commands in `.bash_profile', a "hidden" file in your home directory (see Listing Hidden Files). Thus, to make a command run every time you log in, add the command to this file.

For all new shells after you've logged in (that is, all but the "login shell"), bash reads and executes the commands in the `.bashrc' file in your home directory. Commands in this file run whenever a new shell is started except for the login shell.

There are separate configuration files for login and all other shells so that you can put specific customizations in your `.bash_profile' that only run when you first log in to the system. To avoid having to put commands in both files when you want to run the same ones for all shells, append the following to the end of your `.bash_profile' file:

if [ -f ~/.bashrc ]; then . ~/.bashrc; fi

This makes bash run the `.bashrc' file in your home directory when you log in. In this way, you can put all of your customizations in your `.bashrc' file, and they will be run both at log in and for all subsequent shells. Any customizations before this line in `.bash_profile' run only when you log in.

For example, a simple `.bash_profile' might look like this:

# "Comment" lines in shell scripts begin with a # character.
# They are not executed by bash, but exist so that you may 
# document your file.

# You can insert blank lines in your file to increase readability;
# bash will not mind.

# Generate a welcome message when you log in.
figlet 'Good day, '$USER'!'

# Now run the commands in .bashrc
if [ -f ~/.bashrc ]; then . ~/.bashrc; fi

This `.bash_profile' prints a welcome message with the figlet text font tool (see Horizontal Text Fonts), and then runs the commands in the `.bashrc' file.

A simple .bashrc file might look like this:

# Make color directory listings the default.
alias ls="ls --color=auto"

# Make "l" give a verbose directory listing.
alias l="ls -l"

# Set a custom path.
PATH="/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:~/bin:."

# Set a custom shell prompt.
PS1="[\w] $ "

# Make a long history list and history file.
HISTSIZE=20000
HISTFILESIZE=20000

# Export the path and prompt variables for all 
# variables you define.
export HISTSIZE HISTFILESIZE PATH PS1

This `.bashrc' sets a few useful command aliases and uses a custom path and shell prompt whenever a new shell is run; with the preceding `.bash_profile', this `.bashrc' is also run at login.

When you log out, bash reads and executes the commands in the `.bash_logout' file in your home directory, if it exists. To run commands when you log out, put them in this file.

This executes the clear command, which clears the screen of the current terminal, such as in the xterm window where you type it, or in a virtual console.

NOTE: Some distributions come with default shell startup files filled with all kinds of interesting stuff. Debian users might want to look at the example startup files in `/usr/share/doc/bash/examples/startup-files'.


[<--] [Cover] [Table of Contents] [Concept Index] [Program Index] [-->]