[<--] [Cover] [Table of Contents] [Concept Index] [Program Index] [-->] |
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
.
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). |
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.
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). |
figlet
tool, which displays the
text you give as an argument in a "font" made up of text characters
(see Horizontal Text Fonts).
figlet
, type:
$ figlet $'\\' [RET]
figlet
, type:
$ echo $'\f\266' [RET]
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).
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.
$ [↑] [RET]
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.
$ C-r (reverse-i-search)`': grep
grep
back on the input line, type:
$ C-r (reverse-i-search)`': grep C-r C-r
When a command is displayed on the input line, type [RET] to run it. You can also edit the command line as usual.
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.
$ clear; logout [RET]
hostname
command three times, type:
$ hostname; hostname; hostname [RET] figaro figaro figaro $
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.
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.
apropos
to file `keywords',
type:
$ apropos < keywords [RET]
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.
$ apropos shell bash > commands [RET]
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.
$ apropos shells >> commands [RET]
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.
$ apropos shell bash 2> command.error [RET]
As with the standard output, use the `>>' operator instead of `>' to append the standard error to the contents of an existing file.
$ apropos shells 2>> command.error [RET]
To redirect both standard output and standard error to the same file, use `&>' instead.
$ apropos shells &> commands [RET]
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).
less
,
type:
$ apropos bash shell shells | less [RET]
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.
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.
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.
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.
$ apropos shell > shell-commands & [RET] [1] 6575 $
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").
$ apropos shell > shell-commands [RET] C-z [1]+ Stopped apropos shell >shell-commands $ bg [RET] [1]+ apropos shell & $
If you have suspended multiple jobs, specify the job to be put in the background by giving its job number as an argument.
$ bg %4 [RET]
NOTE: Running a job in the background is sometimes called "backgrounding" or "amping off" a job.
Type fg to move a background job to the foreground. By default,
fg
works on the most recent background job.
$ fg [RET]
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
.
$ fg %3 [RET]
To list the jobs running in the current shell, type jobs.
$ jobs [RET] [1]- Stopped apropos shell >shell-commands [2]+ Stopped apropos bash >bash-commands $
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.
Typing C-c interrupts the foreground job before it completes, exiting the program.
$ cat [RET] C-c [RET] $
Use kill
to interrupt ("kill") a background job, specifying the
job number as an argument.
$ kill %2 [RET]
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.
Use history
to view your command history.
$ history [RET] 1 who 2 apropos shell >shell-commands 3 apropos bash >bash-commands 4 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).
$ history | grep apropos [RET] 2 apropos shell >shell-commands 3 apropos bash >bash-commands 5 history | grep apropos $
This command will show the events from your history containing the text `apropos'. (The last line of output is the command you just typed.)
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).
$ !1 [RET]
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.
$ script log.19990817 [RET] Script started, output file is log.19990817 $ hostname [RET] erie $ apropos bash > bash.commands [RET] $ exit [RET] exit Script done, output file is log.19990817 $
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.
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.
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.
$ PS1='Your wish is my command: ' [RET] Your wish is my command:
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.
bash
prompt -- the current
working directory followed by a `$' character -- type:
$ PS1='\w $ ' [RET] ~ $
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. |
PS1
.
$ PS1='\d (\h)>' [RET] 14 Dec 1999 (ithaca)>
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.
bye
for the exit
command, type:
$ alias bye="exit" [RET]
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.
apropos shell bash
shells
, type:
$ alias ap="apropos shell bash shells" [RET]
This command makes `ap' an alias for `apropos shell bash shells' in the current shell, so typing ap would run apropos shell bash shells.
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.
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.
clear
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] [-->]