This file documents the GNU Bourne Again SHell.

Copyright © 1989, 1990 Free Software Foundation, Inc.

Preface
*******

This manual introduces the GNU Bourne Again SHell (BASH) and explains its role in the operating system.  This manual does not explain the fundamentals of using operating system commands such as ls, cd, and others, nor does it explain how to log into your system.

BASH is a command language interpreter that executes commands read from the standard input or from a file.  BASH is compatible with the Bourne shell (sh), and also incorporates useful features of the Korn shell (ksh) and the C shell (csh).  The intention is that BASH be a superset of the desirable features found in other shells.

BASH is POSIX compliant.

If you read this manual sequentially, you'll find it leads you through the concepts of a shell from its simple beginnings to more complex shell features.  If you are familiar with your machine's operating system and have some experience with shells, then this manual makes a handy reference.

Acknowledgements
================

Many people need to be thanked for their assistance in producing this manual.  Brian and Diane would like to thank Chet Ramey for his production of the BASH man page.  It made the job of writing this manual infinitely easier.

Robert Chassell gave helpful comments on the drafts of this manual. Allan Painter contributed beginning-user examples.  Bennett Todd and Bill Trost contributed very useful samples of shell scripts.  Many thanks to all those who submitted scripts for consideration.  It was difficult to choose only two for inclusion in this manual; all were of very high quality and usefulness.

License
*******

Introduction to Shells
**********************

The shell is a program that the operating system automatically starts up when you log in, so that the system can understand your commands.

Here is a brief listing of some of the things that the Bourne Again SHell (BASH) provides:

  * a built-in language for writing shell programs

  * compatibility with shell programs written for the Bourne shell

  * Emacs and vi style command editing

  * process and job control

  * command aliases

  * shell functions

  * completion of file names, user names, and variable names

The Shell as a Command Interpreter
==================================

When you log on to your system a shell is automatically started for you. Think of the shell as a layer of software between you and the operating system's internal workings, as shown below:

     COMMANDS (typed by you) <------> SHELL <-------> OPERATING SYSTEM

The shell interacts with you, the user, to interpret your commands and tell the operating system to take appropriate action.  The shell stays with you until you log out.

The input and execution of a simple shell command involves the following steps:

 1. The shell displays a prompt (bash$, unless you have specified a different prompt) and waits for you to type a command.

 2. You type a command line, ending with a carriage return.

 3. The shell analyzes that command line, and extracts the command name and arguments.  Here is a template for a simple shell command, with the optional parts between square brackets, [...]:

          COMMAND [ARGUMENTS] [&] RET

     A simple command line consists of a sequence of words separated by blanks (a blank is a space or a tab).  The first word of the command line specifies the name of the command to be executed, and the remaining words are passed as arguments to that command.

 4. The shell tries to locate the specified command as a program in the directories specified in your path.

 5. If the shell can't find the command program you requested, it gives you an error message and provides a new prompt.

     If the shell is successful in locating the requested program, it tells the operating system to execute that program using the rest of the command line as arguments for that program.

 6. If you did not end your command line with &, the program is run in the foreground.  When the program is finished, the operating system returns control to the shell and the shell gives you another prompt.

     If you ended your command line with &, the program is run in the background.While the program is executing the shell waits. The shell doesn't wait for the operating system to finish running the program; rather, the shell immediately gives you a prompt so you can continue typing commands.  (Running a program in the background is useful if the program takes a long time to execute and doesn't need supervision.)

 7. At the new prompt you type in the next command line to be processed and run.  These steps are repeated until you log out.

The Shell as a Programming Language
===================================

BASH has its own built-in, interpreted programming language.

Some of the programming features available to you are:

  * storage of values in variables

  * conditional execution statements

  * user-defined functions

  * looping and other ways of executing commands repeatedly

Notation
========

To indicate special keys or key combinations, this documentation uses the following notations:

C-k
     The text C-k is read as ``Control-K'' and describes the character produced when you hold the Control key (CTL) down and strike the k key.

M-k
     The text M-k is read as ``Meta-K'' and describes the character produced in either of two ways:

          Either hold the META key (if you have one) down and strike the k key

          or type ESC first and then type k.

     Either process is known as metafying the k key.

M-C-k
     The text M-C-k is read as ``Meta-Control-k'' and describes the character produced by metafying C-k (see C-k and M-k just above).

Typing Commands
***************

This chapter deals with the mechanics of typing commands.

Normally, to give a command you type a line and end it with a newline character (usually referred to as RET in this documentation).

In the following example, BASH displayed its prompt (bash$ ), we typed the command who (terminated by a RET, which is not explictly shown in the example), the output of who (a listing of users logged into the system) was displayed, and BASH displayed another prompt.

     bash$ who
     glassw   ttyq0   Apr 15 15:09   (worker-8)
     glassw   ttyq1   Apr 15 20:50   (worker-7)
     cqc      ttyq2   Apr 15 18:15   (worker-9)
     zvona    ttyq5   Apr 15 14:13   (nico)
     painter  ttyd0   Apr 15 21:00
     stf      ttyh4   Apr 15 11:58
     sandiway ttyh9   Apr 13 23:05
     pwu      ttyhc   Apr 15 15:19
     bash$

The following sections explain more about typing commands, including how to correct mistakes as you type a command and how to type a command that is too long to fit on one line.

Typeahead
=========

Your typing is echoed (displayed on the screen) as you type. If you start to type a command before the prompt is displayed, your typeahead, which echoes immediately, appears before the prompt.  It may even be mixed up with output from the command that was executing when you typed it. In order that you can see the actual command you have typed, BASH redisplays your typeahead after the prompt. Don't worry -- though some characters appear on your screen twice, BASH has kept only one copy of them.

The following shows the appearance of my screen when I typed date to find out the current date and time, then typed who to find out who was logged in. I didn't wait for date's output before I started to type, so the wh from who appears in that output. The next prompt is followed by a redisplay of the wh I already typed, followed by the final o.

     bash$ date
     whFri Jan 04 13:47:49 EST 1991
     bash$ who
     gjs        console      Dec 19 15:53
     wisdom     pty/ttyu0    Dec 27 16:11
     jems       pty/ttyu1    Jan  4 10:56
     bash$

Editing the Command Line
========================

To correct an error in the line you are typing, you can type DEL repeatedly to delete one character at a time until you are back to the spot that needs fixing, then continue typing.  Or you can type C-u to delete the whole current line and start over.

However, it is also possible to move the cursor to the place you want to change and correct the error without deleting and retyping everything you've typed after the error.

You can edit the current line as long as you have not typed the RET that terminates it.

Using the editing keys described below, you move the cursor to the place that needs correction and delete or insert the text of the correction.  Then, when you are satisfied with the line, you simply press RET.  The cursor doesn't have to be at the end of the line when you press RET; the entire line will be accepted in any case.

As you type text into the line, you'll notice that characters to the right of the cursor get pushed over to make room for the characters you are typing.  Likewise, when you delete a character behind the cursor, characters to the right of the cursor get pulled back to fill in the blank space created by the removal of those characters.

The rest of this section describes basic command-line editing. See Readline Commands, for a list of all the editing commands.

If you are an Emacs user, you may already be familiar with most of the editing keys described below: All but C-u are the same ones used in Emacs.

Note: If you don't like any of the editing keys, you can change them to be whatever you want (see Customizing Readline).

Moving the Cursor
=================

Here are the basic ways to move the cursor within the line you are typing:

C-b
     Move cursor back (left) one character.

C-f
     Move cursor forward (right) one character.

M-b
     Move cursor backward (left) one word.

M-f
     Move cursor forward (right) one word.

C-a
     Move cursor to the start of the line.

C-e
     Move cursor to the end of the line.

Notice that C-f moves forward a character, while M-f moves forward a word.  It is usually the case that Control keystrokes act on characters, while Meta keystrokes act on words.

Deleting Text
=============

Here are the basic ways to delete text once you have positioned the cursor:

C-d
     Delete the character underneath the cursor.

DEL
     Delete the character to the left of the cursor.

C-k
     Kill the text from the current cursor position to the end of the line.

C-u
     Kill the text from the beginning of the line to the current cursor position. (Note that if the cursor is at the end of the line, this kills the whole line.)

Inserting Text
==============

To insert text into the line, just position the cursor and type the text as you normally do at the end of a line. No special keystroke is needed to indicate that you want to insert.

Clearing the Display
====================

If the screen is cluttered, you may wish to:

C-l
     Clear the screen, reprinting the current line at the top.

Failing to Correct a Command Line
---------------------------------

If you notice an error while typing a command, it is better to fix it (or delete the command and start over) than to let the command execute as is, especially if the command contains any punctuation characters (many of which have special meaning to the shell). Although many sorts of errors will result in perfectly harmless (and sometimes even comprehensible) error messages, other erroneous commands may do things you didn't intend or give you error messages that only a shell wizard can understand. For example, if you accidentally hit * while typing a file name in a command to delete a file, you may end up deleting more than one file (see File Names).

Repeating Earlier Commands
==========================

You can sometimes save typing by retrieving an earlier command. You can reexecute the command as is, or you can edit it before executing it. This is particularly useful if a command gets an error. Instead of retyping it with the error corrected, you can retrieve the command and just fix the erroneous part.

If you are an Emacs user, you may recognize the following commands as the same ones that move to the previous or next line or to the beginning or end of an Emacs buffer. Think of BASH as maintaining an Emacs buffer of your command lines, in which you can see only one line at a time. Each time you end a line (by typing RET), BASH adds that line to the end of the buffer and positions its cursor at the start of the next line.

See History List, for a more complete description of what commands BASH remembers in its history list.

The rest of this section describes the basic commands for accessing previous command lines. See History Commands, for the complete set of commands.

C-p
     Get the previous line from the history list. (Opposite of C-n.) The line is displayed after the prompt as if you had just typed it.

C-n
     Get the next line from the history list. (Opposite of C-p.) The line is displayed after the prompt as if you had just typed it.

M-<
     Get the oldest line in the history list. (Opposite of M->.) The line is displayed after the prompt as if you had just typed it.

M->
     Get the most recent line in the history list. (Opposite of M-<.) This is the line you are typing at the current prompt. Unless you type something after the prompt, this line is blank.

If you're a BASH novice, it is probably best to start by using just C-p and C-n. Type C-p repeatedly to move back as far as you want. If you overshoot, use C-n to go forward again.

Continuing a Command on the Next Line
=====================================

If you don't have room on the line to finish typing your command, type a backslash, \, then RET. A \ at the end of a command line tells the shell that the command hasn't ended, but is to be continued on the next line. The shell will give you a secondary prompt (different from the ordinary prompt, so you can tell that this is a continuation line), and you can continue typing the rest of the command. In this way, you can continue a command over any number of lines. The command is not executed until the final RET (that is, a RET not preceded by a \) is typed.

For example, both of the following commands concatenate the files file1 through file6 together into a single file file1to6.  In the first sequence, the command is split into two lines by ending the first line with a \.  BASH prints a secondary prompt (bash>, unless you have specified a different prompt) to signal that it awaits further input for the current command.

     bash$ cat file1 file2 file3 \RET
     bash>file4 file5 file6 > file1to6RET
     bash$

is equivalent to:

     bash$ cat file1 file2 file3 file4 file5 file6 > file1to6RET
     bash$

Warning:

  * The \ must be the last thing on the line that is to be continued.  If you accidentally type a space after the \, your screen will not look any different, but the command line will be terminated by the RET rather than continued.

  * The multiple command lines are simply concatenated, with no space inserted.  If a space is needed between the last thing you type on one line and the first thing you type on the next line, you must be sure to include the space yourself (either before the \ that ends the first line or at the start of the next line).

Editing Earlier Lines
=====================

Command-editing (see Editing) only works on the current line. If you notice while typing a continuation line that you need to correct an earlier line of the command, you will need to abort the command entry and start over (though you needn't retype everything, if you follow the instructions below):

 1. To avoid losing the line you are in the midst of typing, end it with \RET.

 2. Type C-c to abort command entry and get back to the top level of BASH.

 3. The lines you typed but never executed were nonetheless stored in the command history list.  Use C-p (see History Use) to retrieve the lines of your multi-line command one at a time. Type RET after each correct line, but when you come to the bad line, edit it before typing RET.

Redirecting Input and Output (Basic)
************************************

You may want to send a program's output to a printer instead of to your screen.  Or you may want to use a data file for input, instead of typing input at your keyboard.

Many commands allow input files and output files to be specified as arguments. For commands that don't take such arguments (or whose arguments you don't remember), you can use redirection operators, as explained in this chapter, to redirect input or output to come from or go to a file. You can also redirect input or output to come from or go to another program, by using pipes.

Redirection is performed by the shell, not by individual command programs. The action of the command itself is unchanged by redirection; in general, commands are unaware that their input or output has been redirected. The command reads its input and writes its output as usual, and that input and output automatically come from and go to whatever places the shell has set up. This is accomplished as follows.

Most programs that read from or write to the terminal actually read their input from an imaginary place called standard input, write their ordinary output to an imaginary place called standard output, and write their error messages to an imaginary place called standard error. Before the shell runs the program in a command, it hooks up the standard input, standard output, and standard error to real places, such as your terminal, a file, or another program's input or output.

The following sections tell you how to specify how these standard input and outputs should be hooked up.

Redirection versus file arguments
=================================

Consult the documentation of the specific command you wish to use to see whether you have to use redirection operators in order to make it use files. File Names as arguments are often preferable to redirection operators because they enable the command to know the name of the file it is reading.  (A command can know its arguments, but is not aware of redirection.)  Also, some commands (such as sort) can read more than one input file when the files are specified as arguments, whereas redirection can only specify a single input file.

For example, here are two ways to sort the file unsorted to produce the file sorted-file. The first command gives the file names as arguments, with -o flagging the output file name. The second command uses < to redirect the input and > to redirect the output.

     bash$ sort -o sorted-file unsorted

     bash$ sort < unsorted > sorted-file

However, if you want to combine two input files unsorted-1 and unsorted-2 into one sorted output file, you'll have to give the input files as arguments, because only one input file could be supplied by redirection.  You still have a choice of how to specify the output file.

     bash$ sort -o sorted-file unsorted-1 unsorted-2

     bash$ sort unsorted-1 unsorted-2 > sorted-file

Basic Redirection to Files
==========================

This section shows the basic method for redirecting the standard input, standard output, and standard error to files. See Advanced Redirection, for more complicated forms of redirection.

In general, a simple redirection of input or output to a file looks like this:

     COMMAND REDIRECTION-OPERATOR FILE

The FILE is the file or device you want to use, and the REDIRECTION-OPERATOR is < for input; >, >|, or >> for output; or >& for output and error. Spaces surrounding the operator are optional, but it is a good idea to leave a space before the operator. (Otherwise you might accidentally specify one of the redirections with a file descriptor -- Advanced Redirection.)

>
>|
>>
     instruct the shell to send the command's standard output to the specified FILE instead of to your terminal.

       * If FILE doesn't yet exist, it is created.

       * If FILE already exists:

            * With > and >|, FILE is erased before the first output is written to it.  Be careful: If a file of the same name already exists, its contents are deleted before your command's output is written to that file. If you don't want > to erase existing files, set the shell's noclobber variable; then > with an existing file will generate an error message and leave the file alone.  (But note that >| will clobber existing files regardless of the setting of the noclobber variable.)

            * With >>, the output is appended to the end of an existing FILE.

     Note that >, >| and >> redirect only the standard output; error messages printed by COMMAND, which go to standard error, still appear on the terminal and not in the file FILE.  To redirect error messages along with other output, see >&, below.

     Here's an example of output redirection:

          bash$ who
          glassw   ttyq0   Apr 15 15:09   (worker-8)
          glassw   ttyq1   Apr 15 20:50   (worker-7)
          cqc      ttyq2   Apr 15 18:15   (worker-9)
          zvona    ttyq5   Apr 15 14:13   (nico)
          painter  ttyd0   Apr 15 21:00
          stf      ttyh4   Apr 15 11:58
          sandiway ttyh9   Apr 13 23:05
          pwu      ttyhc   Apr 15 15:19
          bash$ who > users-file
          bash$

     The command who prints onto standard output a list of the users currently logged into a computer system. The simple command who prints onto your screen (the default standard output).  The command who > users-file redirects who's standard output to the file users-file, so that the output of the who command goes into users-file instead of appearing on the screen.

     The following command sequence creates a file containing the current date followed by the list of users currently logged onto the system:

          bash$ date > date-who-file
          bash$ who >> date-who-file
          bash$ cat date-who-file
          Sat Aug 04 11:27:05 EDT 1990
          glassw   ttyq0   Apr 15 15:09   (worker-8)
          cqc      ttyq2   Apr 15 18:15   (worker-9)
          zvona    ttyq5   Apr 15 14:13   (nico)
          painter  ttyd0   Apr 15 21:00
          stf      ttyh4   Apr 15 11:58
          pwu      ttyhc   Apr 15 15:19
          bash$

     The command date prints the system date on standard output. In this example, the output of date becomes the first line of the file date-who-file created with the > redirection operator. The output of the who command is appended to the file date-who-file, because we used the >> redirection operator.  cat simply shows the file's contents on the terminal.

&>
>&
     both instruct the shell to send the command's standard output and standard error to the file FILE, instead of to your terminal.  Both ordinary output and any error messages are written to FILE, interspersed, in the order they are generated.  Of the two forms, the second (>&) is preferred, because it conforms to the convention that output redirection operators start with >.

     As with >, FILE is erased before the first output is written to it.  Be careful: If a file of the same name already exists, its contents are deleted before your command's output is written to that file. If you don't want >& to erase existing files, set the shell's noclobber variable; then >& with an existing file will generate an error message and leave the file alone.

     The example at the end of this section shows how to redirect standard error and standard output to different places.

<
     instructs the shell to get the command's standard input from the specified file FILE instead of from your terminal.

     Here's an example of this type of redirection:

          bash$ wc < date-who-file
               7     39     244
          bash$

     The command wc counts the number of lines, words, and characters it reads from standard input.  Using the standard input redirection operator, <, we made wc read a file as its standard input.  In this example, wc prints the line, word, and character counts for the file date-who-file that was created in the example for >> above using the date and who commands.

     Actually, redirection was not necessary for the above command, since wc accepts the name of an input file as an argument:

          bash$ wc date-who-file
               7     39     244
          bash$

More than one redirection operator can appear in a command. Here's an example that redirects both standard input and standard output:

     bash$ sort < users-file > sorted-list

This example reads the input for the command sort from the file users-file and writes the sorted output to the file sorted-list.  Any error messages are still written to the default standard error, which is your terminal screen.

You cannot redirect a single I/O stream to more than one file: If you specify more than one redirection of the same I/O stream, only the rightmost takes effect. (The shell evaluates redirection operators in the order encountered, from left to right.)  For example, the output of sort in the following goes only to out-file, not to sorted-list.

     bash$ sort < users-file > sorted-list > out-file

In the next example, the output of sort goes to out-file and the error messages go to error-file.  The >& redirects both standard output and standard error, then the > redirects standard output to out-file, overriding the >&.

     bash$ sort < users-file >& error-file > out-file

Pipes -- ``Mix-and-Match'' Commands
===================================

One of the shell's most powerful features is the way it lets you ``mix and match'' commands.  By feeding the output of one command into another command, you can get a combination of behaviors that no predefined command provides.

A pipe connects the standard output of one command to the standard input of another. This has the same effect as redirecting the standard output of the first command to a file, then redirecting the standard input of the second command to come from that file; but the pipe does this with a single command, and stores no intermediate files on disk.

For example, let's say you want to see an alphabetical list of the users logged into the system. There is no command that does this, but there is a command who that produces a list of the logged-in users and a command sort that sorts its input lines. By piping these commands together (making the output of who become the input to sort), you can get the desired sorted list:

     bash$ who | sort

     cqc      ttyq2   Apr 15 18:15   (worker-9)
     glassw   ttyq0   Apr 15 15:09   (worker-8)
     glassw   ttyq1   Apr 15 20:50   (worker-7)
     painter  ttyd0   Apr 15 21:00
     pwu      ttyhc   Apr 15 15:19
     sandiway ttyh9   Apr 13 23:05
     stf      ttyh4   Apr 15 11:58
     zvona    ttyq5   Apr 15 14:13   (nico)
     bash$

Viewing Output by the Screenful
===============================

An extremely important use for pipes is to view the output of a command one screenful at a time, by piping the command's output into the more command.

Let's say you want to see a detailed listing of a directory that contains a large number of files.  If you just type ls -l, the listing will scroll by faster than you can read it. But if you use a pipe to attach the standard output of ls -l to the standard input of the more command, you can page through the directory listing at your leisure:

     bash$ ls -l | more

How to Pipe Commands
--------------------

To pipe the output of one command into the input of another, place a vertical bar, |, between them.  The general format for a pipeline is:

     COMMAND | COMMAND2 [| ... ]

That is, any number of commands are given, separated by vertical bars, |. The standard output of COMMAND1 is connected to the standard input of COMMAND2, and so on.

In order for a pipeline to work, the first command in the pipeline must generate output to the standard output, the last command must accept input from the standard input, and any intermediate commands must both read from standard input and write to standard output.

Commands used between pipe operators are called filters.  They accept input from the standard input and generate output to the standard output. Examples of commands that can be used as filters include sort (which sorts its input lines) and pr (which formats text for printing).

Saving Intermediate Pipeline Data with tee
------------------------------------------

Normally, any data generated by commands in a pipeline exists only momentarily within the pipeline, because the output of each command simply flows into the next command.

The command in the following example outputs the five lines of the file list-files that come first alphabetically:

     bash$ sort list-files | head -5

This works as follows: The command sort list-files sorts the file, sending the sorted data to the command head -5, which outputs the first five lines in its input.  The sorted data is discarded.

If you want to preserve the sorted data, you could first sort the original data into a new file, then look at the head of that file:

     bash$ sort list-files > sort-saved
     bash$ head -5 < sort-saved

On some systems, there is also a way to preserved the sorted data while using a pipeline. To preserve intermediate pipeline data, such as the sorted data in the above example, insert the tee command into your pipeline. (Note: tee is not built into BASH.  It comes with GNU, and may or may not exist on other operating systems.) The tee command takes a file name as its argument and does two things:

  * It copies its standard input to the standard output.

  * It copies its standard input into the specified file. If the file doesn't exist, tee creates it. If the file already exists, tee overwrites it, unless you give tee the -a option, in which case it appends to the file.

(The name tee stands for the T shape of a pipe used in plumbing to split the flow into two parts.)

Thus tee can be used to copy the data passing through a pipeline into a file for later use.  For example, we can insert a tee into the pipeline shown above:

     bash$ sort list-files | tee sort-saved | head -5

Now the output of sort is sent to the tee command, which stores the sorted data in a file called sort-saved and also passes that data on to the next program in the pipeline, head

Redirection in Pipelines
------------------------

You may redirect the standard input of the first command in a pipeline and the standard output and standard error of the last command in a pipeline by using redirection operators (see Redirection) in those commands.

The following example sorts the file list-files (given to sort on its standard input by redirection with <), gives the sorted output to head (by connecting the standard output of sort to the standard input of head with a pipe, |), and stores the first five lines of the sorted output in the file 5lines (by redirecting the standard output of head to that file with >):

     bash$ sort < list-files | head -5 > 5lines

Processes in a Pipeline
-----------------------

Each command in a pipeline is run as a separate process. That is, the commands run simultaneously, in parallel.

The shell waits for all commands in the pipeline to terminate before returning control to you.

The exit status of the pipeline is the exit status of the last command.

File Names: Shorthands and Special Characters
*********************************************

Wildcards
=========

The shell allows you to specify sets of file names using filename patterns containing wildcard characters, so that you don't have to type all of the file names directly.

For example, if you want information about the five files in the current directory that end with .c, you don't have to type the five file names:

     ls -l foo.c bar.c fred.c card.c game2.c

Instead you can type:

     ls -l *.c

The shell interprets the filename pattern *.c as matching all existing file names ending in .c.  The character *, which can match almost any substring of a file name, is called a wildcard character. See Wildcard Constructs, for an explanation of * and the other wildcard constructs.

A single pattern may contain more than one wildcard. For example, *.c* would match all file names that contain .c.

Wildcard Constructs
-------------------

Here are the wildcard constructs and their meanings:

*
     The asterisk matches any sequence of zero or more characters, except that it does not match a period at the beginning of a file name. (If you want * to include initial periods, set the variable glob_dot_filenames.)

     For example: foo* matches any file name whose first three characters are foo, including the name foo itself; *foo matches any file name not starting with . whose last three characters are foo, including the name foo itself; and .*foo matches any file name starting with . whose last three characters are foo, including the name .foo itself;

?
     The question mark matches any single character, except that it does not match a period at the beginning of a file name. (If you want ? to match initial periods, set the variable glob_dot_filenames.)

     For example, foo? matches any four-character file name whose first three characters are foo.  (Note that foo? does not match foo because foo has only three characters.)

[CHAR-SET]
     This character set matches any one character specified by the CHAR-SET. Like a ?, a character set matches a single character.  Unlike the ?, the character set is selective about which characters it will match.

     The CHAR-SET consists of a sequence of any number of characters and/or any number of ranges of characters. The character set matches any of the single characters listed or any of the characters included in the specified ranges.

     For example, [123abcdq] will match any one character from the set 123abcdq; [1-3a-dq] matches exactly the same characters, but it uses hyphens to indicate the ranges of characters from 1 to 3 (inclusive) and from a to d.

     Thus, foo[12] matches foo1 and foo2 and nothing else; foo[a-z] matches any four-character file name whose first three characters are foo and whose fourth character is any lower-case letter; and foo[a-z12] matches any four-character file name whose first three characters are foo and whose fourth character is 1, 2, or any lower-case letter.

[^CHAR-SET]
     This matches any one character not included in the given CHAR-SET, where the CHAR-SET is as specified above for the [CHAR-SET] case. For example, foo[^a-z12] matches any four-character file name whose first three characters are foo and whose last character is not 1, 2, or a lower-case letter.

[!CHAR-SET]
     This is the same as [^CHAR-SET] if history substitution is disabled. Otherwise the ! invokes history substitution (see History).

How Wildcards Work
------------------

Each command word that contains a wildcard character is expanded, which means it is replaced by a sequence of words, one for each file that matches the pattern. If *.c in the command ls -l *.c expands to foo.c bar.c fred.c card.c game2.c, the ls command sees these five file names as its arguments; it never sees the *.c.

Normally, a filename pattern that doesn't match any files is left in the command as is (it expands to itself).  For example, *.foo is left as is if there are no files ending in .foo, so in the following example the ls command gets *.foo as its argument and reports that there is no such file (which is what you want to know).

     bash$ ls -l *.foo
     *.foo not found
     bash$

If for some reason you don't like this behavior, you can set the variable allow_null_glob_expansion.  When that variable is set, a pattern that doesn't match anything is removed from the command (expands to a null file name).  In the above example, the *.foo would disappear, and ls would get no arguments, so it would report on all files in the current directory.

Warning: A command word containing a wildcard construct is expanded to a sequence of file names whether or not you intended it to be a file name.  At the time the expansion takes place, the system does not know or care whether it makes sense to treat the word as a file name.

Using echo to Preview Wildcard Expansion
========================================

If you are going to use wildcards for something dangerous, like deleting a group of files, it is a good idea to be sure you know what files the pattern will match.

To find out how wildcard characters will be expanded without actually executing your command, use the echo command to preview the expansion of a filename pattern.  The echo command simply displays its arguments fully expanded, with any pattern that doesn't match anything left as is (or deleted, if you have set allow_null_glob_expansion -- Wildcard implementation).

For example,

     bash$ echo rm *.log *.foo
     rm bash.log *.foo
     bash$

shows that if I ask to delete (with the rm command) all files ending in .log or .foo, I will be deleting only bash.log. The pattern*.log was expanded to the single file name that matched, namely bash.log, and *.foo was not expanded because it did not match any existing file names.

File Names Containing Special Characters
========================================

Normally, file names are made up of ``ordinary'' characters -- alphanumeric characters (letters and numbers), periods (.), and a few other characters (such as _ or ~) that have no special meaning to the shell.  For example: the file containing this documentation is named bash.texinfo; a backup version of this file saved for me by Emacs is called bash.texinfo.~1~; and the file in which BASH keeps track of commands I have issued (see History List) is called .bash_history.

If a file name contains a `special'' character -- a character that has special meaning to BASH, you must quote it to prevent BASH from giving the character its special interpretation. In particular, you must quote the following characters if you need to include them in a file name:

       !  |  &  ;  <  >  (  )  $  `  '  "  \  *  ?  [  ]  #

See Quotation, for information on how to quote.

Tilde Expansion
===============

You can avoid having to type long directory pathnames by using a shorthand for your home directory (and even other users' home directories) and for the directory you were last connected to. All of these directory abbreviations start with ~.

You may also see this home-directory shorthand in program output. For example, when you ask Emacs to find a file, it uses ~ instead of spelling out your home directory in the default pathname in the file-name prompt.

When a tilde character (~) appears at the beginning of a word in a command, it is treated as follows:

~
~/...
     Tilde alone (or followed by a slash) is replaced by the value of the variable HOME, or by your home directory if HOME is unset.

~LOGIN-NAME
~LOGIN-NAME/...
     Tilde followed by someone's login name is replaced by that person's home directory.

~+
~+/...
     Tilde followed by a plus sign is replaced by the value of the variable PWD, which is the directory you are connected to. (Thus ~+ is the same as ..)

~-
~-/...
     Tilde followed by a minus sign is replaced by the value of the variable OLDPWD, which is the directory you were previously connected to.

In the following example, I change directories and copy a file from the first directory to the second:

     bash$ cd /top/next/a-subdirectory
     bash$ cp ~-/file-to-copy .
     bash$

Note for advanced users: The above ~ constructs can also be used in pathnames that are stored in variables. For example, you can use pathnames with tildes in the PATH, MAILPATH, and CDPATH variables. In such variables, any pathname (not just the first) can start with ~.  That is, ~ can appear after a :, which separates pathnames.

The Command History List
************************

BASH maintains a list of the commands you have given it most recently, so that you can reuse earlier commands or just review what you did.

This section explains what is actually remembered and how you can influence that by changing the values of shell variables. The following sections explain how to make use of the command history. See Basic Variable Mechanics, for general information on shell variables.

The length of the history list is controlled by the HISTSIZE shell variable.  By default, the value of this variable is 500; that is, the shell saves the last 500 command lines. You can make the length of the history list bigger or smaller by changing the value of the HISTSIZE variable.  A value of zero means no lines are saved.

In this example, we check the value of HISTSIZE and find that it has the default value of 500, then we reduce the value to 128:

     bash$ echo $HISTSIZE
     500
     bash$ HISTSIZE=128
     bash$

The command history does not start out empty whenever you log in. Rather, commands are saved from session to session.  Old commands are erased from the list only when the length of the list exceeds HISTSIZE.

The way BASH remembers commands between sessions is to store them in a file. By default, the file is ~/.bash_history in your login directory. You can change this file name, if you want, by setting the HISTFILE variable.

Normally, all commands are remembered in the history list. You can stop the recording of command lines beginning with a space or of consecutive identical command lines by setting the history_control variable, which is not set by default.

history_control=ignorespace
     stops lines beginning with a space from being recorded.

history_control=ignoredups
     stops a line identical to the last one in the history list from being recorded.

(Sorry, but there is to way to stop both kinds of command recording at once.)

To see the history list, use the history command (see History). You could also look at the file in which BASH saves history, but that is normally updated only when you exit from BASH, so it will contain the history as of the end of your last session rather than the current history.

To reuse earlier commands (or portions of earlier commands), use Emacs-style keystrokes (see History Use) or history substitution (see History).

Customizing Shell Behavior
**************************

You can control some aspects of the shell's behavior, by changing values (such as how often the shell checks whether you have new mail) or by enabling or disabling features (such as whether ! invokes history substitution -- if you don't know what that is, you should probably disable it).

Many parts of this manual include information on how to customize the behavior being described. This chapter covers some basic customizations that don't fit naturally into other topics or that are especially recommended for BASH novices.

To try out a customization command, you can simply type it and see if you like the changed behavior. But you should not waste time retyping your favorite customization commands each time you log in. Instead, the commands you always want in effect should be put into a startup file that BASH automatically executes whenever you log in (see Login script).

Shell Variables
===============

One way to affect shell behavior is to set variables used by the shell.

See Basic Variables, for documentation of some of the more basic variables.  Other variables are covered where appropriate throughout this manual. See Shell Vars, for documentation of all the variables set or used by the shell.

Some of the mechanics of manipulating shell variables are given here (see Basic Variable Mechanics). See Variable Mechanics, for more complete information.

Manipulating Shell Variables
----------------------------

To find out the value of a variable, type echo $NAME, where NAME is the variable of interest.  (Be sure to include the $; if you omit it, echo just repeats the NAME itself.)

To change the value of a variable, type NAME=NEW-VALUE, where NAME is the variable you want to change and NEW-VALUE is the new value you want it to have.  Don't leave any blank space around the =.

Warning: Be careful to type variable names exactly as they are shown here, matching uppercase and lowercase letter exactly.  If you type a name wrong before an =, you will either change the wrong variable or create a new variable; if you type a name wrong after echo $, you will examine the wrong variable.

In the following example, we ask for the value of the MAILCHECK variable, which is 600, then change it to 0 and verify our change.

     bash$ echo $MAILCHECK
     600
     bash$ MAILCHECK=0
     bash$ echo $MAILCHECK
     0
     bash$

Basic Shell Variables
---------------------

This section documents some basic shell variables whose values you might want to change.  For example, if you use more than one computer, you might want to change the shell prompt to be the name of the computer you are using instead of bash$ .  See Shell Vars, for documentation of all the variables set or used by the shell.

Directories
===========

HOME
     This holds the default argument for the cd command.  HOME is set to your login directory when you log in, so that a simple cd command will return you to your login directory at any time.

     For example, I may want to frequently return to the directory where I work on GNU projects:

          bash$ HOME=/usr/jems/gnu
          bash$

     Now a simple cd command will return me to /usr/jems/gnu instead of to /usr/jems.

PATH
     This is the search path the shell uses when looking for program files referenced in commands.  It holds a sequence of directory names separated by colons, to be searched from left to right.

     For example:

          /usr/gnu/bin:/usr/local/bin:.:/usr/ucb:/bin:/usr/bin/X11:/usr/bin

Mail
====

MAILCHECK
     This specifies the amount of time that must pass before the shell will check whether your mail file (the file named by the MAIL variable) has changed.  The default is 60 seconds (1 minute).  An interval of 0 causes the shell to look for mail before printing each prompt.

     For example,

          MAILCHECK=600

     causes the shell to check for mail before printing a prompt if 600 seconds have passed since the last check.

Prompts
=======

When executing interactively, BASH displays the primary prompt (stored in the variable PS1) when it is ready to read a command, and the secondary prompt (stored in the variable PS2) when it needs more input to complete a command.

PS1
     This is the primary prompt string.  By default it is bash$ . (Actually, the value in PS1 is bash\$ , which prints as bash$ unless you are a superuser.)

     The following example sets the primary prompt string to be your login name, followed by an @ and the name of the computer, followed by a dollar sign and a space (for example, jems@zurich$ ).  The variable value is enclosed in quotes (either double quotes, as shown here, or single quotes) so that it can include a space.  The special codes \u and \h for the user name and host name, as well as other codes useful in prompts, are explained below.

          PS1="\u@\h$ "

PS2
     This is the secondary prompt string, which is printed whenever bash needs more input to complete a command.

     By default it is bash>. For example, we can change the secondary prompt string to more>:

          PS2="more>"

     Note that the secondary prompt, unlike the primary prompt, normally doesn't end in a space.  A space might fool you into thinking the lines of a multi-line command were automatically separated by a space, whereas they are actually run together exactly as typed (see Continuation).

The values of PS1 and PS2 can contain special character sequences beginning with \ that are decoded as follows.  (That is, the \ and the following character are replaced by what they stand for when the prompt is printed.)

\t
     The time.

\d
     The date.

\n
     Carriage return and line feed (CRLF).

\w
     The full pathname of the current working directory (the value of the variable PWD).

\W
     The last element of the current working directory (the last directory in the value of the variable PWD).

\u
     Your username.

\h
     Your machine's hostname.

\#
     The command number of this command (consecutively numbered since login, starting with 1).

\!
     The history number of this command (the position of this command in the history list -- History List).

\\
     A backslash.  Since \ in a prompt normally isn't printed, but rather gives the next character a special meaning, if you want a \ in your prompt you must put \\ in the prompt string.

\s
     The name of the shell (the basename of the positional parameter $0).

\$
     $ unless you are the superuser, in which case it is #.

\NNN
     The character that has the given octal code.

For example, if for some reason you did

     PS1="\d \t\n\u@\h\n\w \#$ "

you would have a ridiculously long, multiline prompt, consisting of:

 1. the date and time (separated by a space);

 2. your user name and host name (separated by an @);

 3. your working directory, a space, the number of this command (numbered from 1 since you logged in), a $, and a space.

     bash$ PS1="\d \t\n\u@\h\n\w \#$ "
     Sat Feb  9 14:03:58
     jems@zohar
     ~/gnu 4$ who
     jems       pty/ttyu0    Feb  9 11:38
     gjs        pty/ttyu1    Feb  8 15:16
     Sat Feb  9 14:04:01
     jems@zohar
     ~/gnu 4$

Note for advanced users:

After the prompt string is decoded, it is expanded via parameter expansion and command substitution unless the variable NO_PROMPT_VARS is set,

The set Command
===============

You can use the shell's built-in set command to turn shell options on and off (see Built-in).  Here are some option settings you might want to use:

set -o histexpand off
     disables history substitution (see History). If you don't know what history substitution is, it is a good idea to disable it.

Background and Foreground Processes
***********************************

This chapter explains how to run commands in the background, so that you can do more than one thing at a time, and how to interrupt commands that are running.

First we present a short scenario that illustrates most of the facilities covered in this chapter.  The rest of the chapter provides full explanations of these facilities.

     bash$ monthly-accounting
     C-z
     bash$ bg
     **is job & proc # printed here as for & ?
     bash$ make >& log &
     [1] 18432
     bash$ emacs
     C-z
     bash$ jobs
     **show both background jobs running & suspended foreground job
     bash$ fg
     ...
     bash$ **a done notice for one of the background jobs
     bash$ wait
     **done notice for other background job
     bash$

In this example, we gave the command monthly-accounting, which started our monthly-accounting program (in the foreground).  We didn't want to sit there waiting for it to finish, so we interrupted it (C-z) and continued it running (bg) in the background. We then started a program compilation (make...) in the background (&).  While those background jobs ran, we started up emacs. After a while we wanted to see how the background jobs were coming along, so we interrupted the foreground job (C-z) and asked about our jobs.  The jobs command reported on our two background jobs and also told us about our suspended emacs job.  We resumed the emacs program (fg).  When we exited from emacs, BASH reported that our make job had finished.  We decided to wait for the monthly-accounting job to finish also (wait).

Starting a Job
==============

Commands such as those shown in most of our examples are run in the foreground.  That is, the command runs and you do not get another BASH prompt (and the opportunity to run another command) until it finishes.  This is appropriate for short or interactive tasks.

If a program will be running a long time and does not require supervision or input from the terminal, it may be best run in the background.  This leaves your terminal free for other tasks.

Starting a Background Job
-------------------------

To run a command in the background, place an ampersand, &, at the end of the command line.  For example, the following command runs make (which recompiles a program as specified by a data base in the current directory) in the background (&), redirecting make's standard output and error messages to the file log:

     bash$ make >& log &

In this example, the command does not read from the standard input, so we had no reason to redirect standard input.  If a background command uses its standard input, you should normally redirect it, because the command cannot read from the terminal (which you are using for other things).  If a background task needs input from the standard input and you have not redirected the standard input:

  * On a system with job control (such as GNU), the background task is suspended if it needs input from the standard input.  You can then bring the task to the foreground (see Resuming) and type the input.

  * On a system without job control (such as SYSTEM V), the background task is given a null string if it needs input from the standard input.

You should usually redirect the background command's standard output as well (as shown in the above example), unless you want the output to be interspersed with your other work on the terminal.  If your background task sends output to the standard output and you did not redirect the standard output, this output appears on your terminal, even if you are running another program.

When you run a background command, the shell prints out its job number and the PID of the last process in the pipeline (see Numbers).  In the following example, BASH assigns our background command a job number of 1.  It assigns a PID of 18449 to the last process in the pipeline, wc > count-file.

     bash$ ls -l | wc > count-file &
     [1] 18449
     bash$

Notification of Background Job Termination
------------------------------------------

When a background job is finished, BASH reports its job number, the word Done, and the command line itself:

     [1]+  Done              ls -l | wc >count-file

Normally the shell reports on jobs only when it issues a prompt, so it doesn't interrupt what you are doing.  If you wish to be told of changes in job status immediately (not just when you get the next shell prompt), set the notify variable, as follows:

     bash$ notify=

Waiting for Background Jobs to Terminate
----------------------------------------

If you want to wait for some or all of your background jobs to finish before issuing any more commands, you can save yourself the trouble of keeping track of the termination notices (see notify) or repeatedly typing the jobs command (see Jobs command) by using the wait command to wait for the background jobs to finish.

wait
wait JOB_SPEC
wait PID
     The wait command waits for active background processes to finish.  It suspends operation of your terminal until the specified background job (JOB_SPEC) or background process (PID) is finished.  If no job or process is specified, wait waits for all currently active jobs to finish.

     JOB_SPEC is any job specification and PID is a PID (see Numbers).

     Let's assume that you want to start three lengthy jobs running concurrently and then want to wait for all three jobs to finish before continuing.  Here's how you'd do it:

          bash$ find / -name core -print >& core_list &
          [1] 2240
          bash$ grep "Experience" /home/* >& exper_list &
          [2] 2241
          bash$ ls -lR / >& dir_list &
          [3] 2242
          bash$ wait
          [1]   Done                find / -name resume -print >& resume_list
          [2]-  Done                grep "Experience" /home/* >& exper_list
          [3]+  Done                ls -lR / >& dir_list
          bash$

     In this example, three long jobs are performed simultaneously: each job is performed in background by the & operator at the end of the command. Notice that each job has its standard output and standard error redirected to a file with the >& operator so that the jobs do not write output or error messages to the screen while they are running in the background.  The wait command waits for all three commands to finish before allowing BASH to continue.

Jobs, Processes, and their Identifiers
======================================

Each pipeline run by the shell is considered a separate job.  (A pipeline is a set of commands joined by pipes (see Pipes), or a command without pipes -- which can be though of as the simplest possible pipeline, with only 1 command and 0 pipes.)  Each command in the pipeline is run in its own process (that is, they run simultaneously).  Hence a job consists of one or more processes.

There are a number of commands that act on jobs or processes.  (For example, there are commands to suspend a job or kill a process.)  If you give a command for a job (for example, killing the job), this applies to all the processes in the job.  If you give a command for a process, only that process is affected.

To specify the desired job or process in a command, you may need to refer to it by number.

  * Every process has an identifying number, called a PID (Process IDentifier).  PIDs, which are assigned by the operating system, are unique throughout the entire system: No two processes, even belonging to different users, can have the same PID at the same time.

  * Jobs are identified by small job numbers, which are assigned by BASH. Unlike PIDs, these are not unique throughout the system: Any number of users may have a job 1 at a given time.  However, at any moment, all your jobs have numbers that are different from each other, which is all you need to uniquely identify them in commands.

When you run a background command, the shell prints out its job number and the PID of the last process in the pipeline (see Background).  In addition, you can find out these numbers by using the jobs command or the ps command (see Jobs command).

To refer to a process in a command, use its PID.  To refer to a job in a command, use a job specification having one of the following forms:

%NUMBER
     refers to the job whose number is NUMBER.  For example, %1 refers to job number 1.

%STRING
     refers to the job whose command line (the command that started the job) starts with STRING.  For example, %emacs refers to an emacs job. If there is more than one job whose name begins with the string, you'll be given an error message.

%?STRING
     refers to the job whose command line (the command that started the job) contains STRING.  For example, %?mac may refer to an emacs job.  If there is more than one job whose name contains the string, you'll be given an error message.

%
%+
%%
     all refer to the current job (the last job stopped or placed in the background, see current job).

%-
     refers to the previous job (the second-to-last job stopped or placed in the background, see current job).

Note that a job specification starts with a % character.  In certain contexts, however, where it is clear that a job is being referred to, it is possible to omit the %.

Finding Out Out What Jobs and Processes You Have
================================================

To find out what stopped (suspended) and background jobs you have, you can use the jobs command.  The following example shows that we have three suspended jobs.

     bash$ jobs
     [1]   Stopped    rn
     [2]-  Stopped    vi file
     [3]+  Stopped    emacs file2
     bash$

Use the -l flag with jobs to see the jobs' processes as well:

     bash$ jobs -l
     [1]+ 18448 Done         ls -l
          18449              | wc >count-file
     bash$

The ps command reports more detail about your active processes than jobs does, but it treats the processes as individuals and doesn't group them into jobs.  When typed without options, ps gives you the following information. (Note that ps is not built into BASH, so its output is different from system to system; however, the basics remain the same.)

PID
     The process identification number.

TTY
     The terminal from which the process was started.

TIME
     The amount of computer time the process has used so far.

COMMAND
     The name of the process.

Here's an example of the output of ps:

     bash$ jobs
     [1]+  Stopped             emacs
     bash$ ps
       PID TTY      TIME COMMAND
      2249 ttyp0    0:00 ps
      2184 ttyp0    0:00 emacs
      2170 ttyp0    0:00 bash
     bash$

This ps command shows that we have three processes: the ps process itself, an emacs process (which we presumably suspended earlier), and the bash process itself.  (ps, unlike jobs, reports on foreground as well as background processes.)  BASH has assigned job number 1 and process number 2184 to emacs.

See ps (The GNU Utilities Manual), for more information.

Current Job and Previous Job
----------------------------

The + and - in the output of jobs identify the ``current job'' and ``previous job'' respectively.  The job most recently stopped (suspended) or put in the background is called the current job. It is marked with a plus sign, +, in the jobs listing.  The second-to-last job stopped or put in the background is called the previous job.  It is marked with a minus sign, -, in the jobs listing.  When the current job is terminates or is moved to the foreground, the previous job becomes the new current job.

The concept of ``current job'' is used for defaulting arguments to the fg and bg commands (see Resuming).

Interrupting a Job
==================

Interrupting the Foreground Job
-------------------------------

You may want to abort the program you are currently running (in the foreground), or you may want to interrupt it temporarily in order to do something else.

The following keys stop the foreground job, placing it in a type of ``suspended animation'' so that it can be resumed if desired (see Resuming).

C-z
     This stops (suspends) the foreground job immediately.

C-y
     This is similar to C-z except it causes the process to be stopped (suspended) only when that process attempts to read input from the terminal.

Note for advanced users: C-z and C-y will not suspend the shell itself. To suspend a shell, such as one started with the su command, use the suspend command (see Built-in).

The following keys kill the foreground job. The job cannot be resumed.

C-c
     This kills the foreground job immediately.

C-\
     This kills the foreground job immediately and it is much harsher than C-c. This method usually produces a core (memory) dump for later analysis.

All of the above keystrokes can be reassigned to other keys, by using stty. We are just covering the most common keyboard methods of stopping jobs. Your operating system manual will tell you about other keyboard interrupts and how to remap your keyboard.

No matter which method you use (except C-c), the shell tells you when your program, or job, has been ``Stopped'', and prints another prompt.

Interrupting a Background Job
-----------------------------

You cannot use the keyboard interrupts (see Interrupt foreground) to interrupt a background job, since background jobs do not listen to the terminal.

To suspend or terminate a background job, you can do either of the following:

  * Use the kill command (described below).

  * Move the job to the foreground (see fg<>bg) then use one of the keyboard interrupts for foreground jobs (see Interrupt foreground).

kill [-SIGSPEC] PID
kill [-SIGSPEC] JOB_SPEC
     Send the process identified by PID or all processes in the job identified by JOB_SPEC the terminate signal, or the signal specified by SIGSPEC, if given. PID is a process identification number and JOB_SPEC is a job specification (see Numbers). Signals are specified either by number or by name, as explained below.

kill -l
     This lists all the possible signal names (and numbers). It does not affect any jobs or processes.

Here's a summary of the most common and useful signals. In the kill command, you can use any of the following:

  * the name shown  -- e.g. SIGKILL

  * the part of the name after SIG -- e.g. KILL

  * the lowercase version of the part of the name after SIG -- e.g. kill

SIGHUP
     This is a gentle signal you can send to processes that you want to kill when you want to allow them to clean up after themselves (for example, delete temporary files, kill subprocesses, etc.).  It is a good practice to try to kill jobs with this signal first, before trying any of the harsher signals.  Some programs see this signal as a request for them to re-initialize some internal state or re-read a startup file, so this signal is not always used strictly for killing a process.

SIGINT
     This is the signal generated (normally) by C-c on the keyboard. This signal will kill most processes, although a program may choose to ignore SIGINT.  SIGINT also allows a process to clean up after itself before dying.

SIGQUIT
     This is the signal generated (normally) by C-\ on the keyboard. SIGQUIT is identical to SIGINT except that it requests that the operating system produce a diagnostics file called a core dump, which is placed into a file named core. This can be useful for debugging.

SIGTERM
     SIGTERM is similar to SIGINT except that it is normally produced by a program and not from the C-c on the keyboard.  Note that some programs treat SIGTERM differently from SIGINT.

SIGKILL
     SIGKILL is the harshest ``kill'' signal.  It kills a process without warning and without allowing the process to clean up after itself. SIGKILL should be used as a last resort, if SIGHUP, SIGTERM, SIGINT, and SIGQUIT don't work.

SIGTSTP
     SIGTSTP is the signal sent (normally) by the C-z key on the keyboard. Some programs may ignore this signal.  This signal does not kill the process but instead stops the process, putting the program into a suspended state.

SIGSTOP
     SIGSTOP is identical to SIGTSTP except it is not generated from the keyboard by C-z; it is must be sent with kill or from within a program.

SIGCONT
     SIGCONT causes a stopped process to continue running.  A stopped process is sent this signal by BASH when the fg and bg commands are used.

The following example terminates a tip process that has been stopped earlier:

     bash$ jobs -l
     [1]+ 29854 Stopped        tip
     bash$ kill -HUP 29854
     [1]+ Hangup               tip
     bash$ jobs
     bash$

For a tip process, it is especially useful to use the -HUP signal so that tip cleans up the UUCP lock files that it leaves around.

Logging Out With Stopped Jobs
-----------------------------

If you have stopped jobs that you have forgotten about and you try to log off, you will be given a warning that you have ``Stopped jobs'' and will not be allowed to log off.  If you continue to try to log off, you will eventually be successful, but the operating system will kill (terminate) all your stopped jobs.

It is much better to bring the stopped jobs to the foreground (see Resuming) and terminate them properly, so that can clean up after themselves (save files, etc.).

You can also prevent jobs from being killed when you log off by using the nohup command (see nohup).

Resuming a Suspended Job
========================

A job that has been suspended (see Stopping) can be resumed. That is, you can make it continue from where it left off. The resumed job can be run either in the foreground or in the background, regardless of whether it was foreground or background when it was interrupted.

The following methods of resuming jobs are described more fully below:

  * To resume a suspended job in the foreground, use the fg command or just type a job specification (see Numbers).

  * If you set the auto_resume variable, typing a command may resume a suspended job instead of starting a new one.

  * To resume a suspended job in the background, use the bg command or just type a job specification (see Numbers) followed by an ampersand (&).

fg
fg JOB_SPEC
JOB_SPEC
     Bring the specified job into the foreground, and resume running it.  If JOB_SPEC isn't specified, fg acts on the current job (%).

     The following example resumes the current job in the foreground:

          bash$ fg

     The following example resumes a stopped du process in the foreground:

          bash$ %du

bg
bg JOB_SPEC
JOB_SPEC &
     Place the specified job in the background, and resume running it as if it had been started with &.  If JOB_SPEC is omitted, bg acts on the current job (%).

          bash$ find / -name resume -print >& resume_list
          C-z
          [1]+  Stopped   find / -name resume -print >& resume_list
          bash$ bg
          find / -name resume -print >& resume_list &
          bash$

     Here we started the find command in the foreground but then stopped it (with C-z) and placed it in the background when we got tired of waiting for the command to finish.

     The following example places job 2 in the background:

          bash$ jobs
          [1]-  Stopped   find / -name resume -print >& resume_list
          [2]+  Stopped   ls -R / >& dir_list
          bash$ %2 &
          ls -R / >& dir_list &
          bash$

auto_resume=
auto_resume=exact
     If you create the auto_resume variable (e.g. by typing auto_resume=), then if you type a command that matches a suspended job's command, the suspended job is resumed instead of a new job being started. If the value of auto_resume is exact (you set auto_resume=exact), then you must type the entire job name; if the value is anything else, then only part of job name is enough to resume it. If there is more than one job with such a name, the job with the highest number is resumed.

     For example, assume that you have a stopped Emacs job:

          bash$ jobs
          [1]+  Stopped             emacs -f rmail

       * If you have not set auto_resume, then the command

               bash$ emacs

          will start another Emacs job, and the old job will remain suspended.

       * If you have set auto_resume, the above emacs command will resume the stopped Emacs job.

       * If you have set auto_resume to anything but exact, an abbreviated command (such as ema) will also resume the stopped Emacs job.

Moving a Job Between Foreground and Background
==============================================

To move the job that is running in the foreground to the background, suspend the job (see Stopping) and then resume it in the background (see Resuming).

To make a job that is running in the background be the foreground job, pretend the job has been suspended (though there is no need to actually suspend it) and ``resume'' it using any method of resuming jobs in the foreground (see Resuming).

Preventing Jobs From Stopping Using nohup
=========================================

The nohup command prevents commands from stopping, or being killed, when you log out. Normally when you log off your system, any commands or processes that are running in the background are terminated. The nohup command prevents hangup signals (SIGHUP, normally generated when you log off), interrupt signals (SIGINT, normally generated by C-c), and quit signals (SIGQUIT, normally generated by C-\) from terminating your program.

The format of the nohup command is:

     nohup COMMAND-LINE

where COMMAND-LINE is the command you don't want interrupted. Any output the COMMAND-LINE produces is put into a file called nohup.out in your current directory. (If this file cannot be written to your current directory, nohup places it in your home directory.)

THIS DESCRIPTION IS MACHINE SPECIFIC, UNLESS WE HAVE A GNU NOHUP (bfox).

The nohup command increments the priority by 5. (see nice, for an explanation of priority.).  Make sure that you invoke nohup from the shell prompt with &, so that it won't respond to interrupt signals, or take input from the next user.

Combining Several Commands on One Line
**************************************

Sequential Commands
===================

There are several ways to type several commands in one command line, such that the commands are executed one after another. You can either make the sequence execute unconditionally, as if you had typed the commands one after another at the shell prompt; or you can make execution of the sequence stop early depending on the outcome of one of the commands, as if you had typed the commands one at a time and decided whether to continue as you went along.

To do this, give a command of the form

     COMMAND [SEPARATOR COMMAND]

That is, give any number of commands with an appropriate separator between each pair, as defined in the following:

;
     allows you to put several commands on the same line, to be executed sequentially. Separate each command from the next with a semicolon, ;.

     No command in the sequence is executed until you end the line (press RET). Then the commands are executed in order, from left to right, as if you had typed each separately and waited for it to finish before typing the next.

     For example:

          bash$ cp test test-old; du > test; ls -l test*

&&
     indicates conditional execution of commands in the sequence. && means AND; the trailing commands are executed only if the preceding commands are executed successfully.

     For example, if there is no file named garbage.test, then an attempt to list directory information for such a file (ls -l...) and an attempt to view its contents (cat...) will both fail:

          bash$ ls -l garbage.test ;  cat garbage.test
          garbage.test not found
          cat: cannot open garbage.test
          bash$

     But if && instead of ; joins the two commands, the second command is performed only if the first command is successful.  Since the file garbage.test doesn't exist, we get the error message associated with ls and cat isn't run:

          bash$ ls -l garbage.test && cat garbage.test
          garbage.test not found
          bash$

||
     indicates conditional execution of commands in the sequence. || means OR; the remaining commands are executed only if the preceding commands are not executed successfully.

     For example:

          bash$ cat garbage.test || cat junk.test
          cat: cannot open garbage.test
          This is the contents of junk.test.

     The first cat failed to find garbage.test, so the second cat was performed.

Simultaneous Commands
=====================

There are two ways to type several commands in one command line, such that the commands are executed simultaneously, in separate processes. You can specify either independent commands or commands whose inputs and outputs are linked together.

To do this, give a command of the form

     COMMAND [SEPARATOR COMMAND]

That is, give any number of commands with an appropriate separator between each pair, as defined in the following:

|
     joins commands together into a pipeline. The standard output of each command is redirected (connected) to the standard input of the next command in the sequence. See Pipes.

&
     causes each command to run in the background. The commands are executed simultaneously in the background, as if you had typed each one separately, terminated with &. See Job Control.

     Note: & actually terminates commands rather than separating them.  This is a difference from the other command combiners in this chapter.  Thus be sure to put a & after the last command as well as between commands, or the last command will not run in the background.

Mixtures of Sequential and Simultaneous Commands
================================================

Any or all of the command separators described in this chapter (;, &&, ||, |, &) can be used in a single command.

The order of precedence (from highest to lowest) is

|
     pipeline

&& and ||
     ``and'' and ``or'', equal precedence, processed from left to right

; and &
     sequential and background, equal precedence, processed from left to right

However, if you have a mixture of operators, you should usually group the subcommands with parentheses or braces (see Grouping), rather than assume you know how the command will be interpreted.

Command Line Editing
********************

BASH provides powerful facilities for editing the command line you are currently typing, so as to minimize the amount of typing needed to fix mistakes. It also includes facilities to save typing by giving you access to earlier commands and by completing things (such as file names) that you have not finished typing.

The command-entry features described here are not specially programmed into BASH. Rather, they are provided by the readline library, which is used by a number of other GNU programs besides BASH. This means that you can use the same typing and editing facilities with a variety of programs.

By default, readline has Emacs-like key bindings. That is, most features that Emacs also has (such as moving the cursor over words or characters) are invoked by the same keystrokes as in Emacs. See Customizing Readline, for how to change any key bindings you don't like and customize other aspects of readline's behavior.

readline Commands
=================

The following sections list all the functions provided by readline. Each entry consists of

  * the function name You do not need the function name unless you want to change the key binding (see Customizing Readline).

  * the default key binding (in parentheses) This is the key you press to invoke the function. If no key binding is shown, then you can't use the function unless you bind it to a key (see Customizing Readline).

  * a short description of what the function does

Moving the Cursor
-----------------

Here are the readline cursor movement commands:

beginning-of-line (C-a)
     Move to the start of the current line.

end-of-line (C-e)
     Move to the end of the line.

forward-char (C-f)
     Move forward (right) one character.

backward-char (C-b)
     Move backward (left) one character.

forward-word (M-f)
     Move forward (right) one word.

backward-word (M-b)
     Move backward (left) one word.

Changing the Command Text
-------------------------

Here are the readline commands for text manipulation:

quoted-insert (C-q, C-v)
     Add the next character that you type to the line verbatim.  This allows you to insert a control character, for example, and not have it act as an editing key. For example, if you want to search for a C-l in a file, you can type the C-l argument to the grep command by typing C-q C-l.

tab-insert (M-TAB)
     Insert a tab character. (A TAB character itself normally invokes completion rather than being inserted into the command line -- see Completion.)

self-insert (a, b, A, 1, !, ...)
     Insert the typed characters verbatim. All printing characters except TAB and newline (i.e., all non-control, non-meta characters) are inserted as typed.

transpose-chars (C-t)
     Interchange the character before the cursor with the character at the cursor and position the cursor after both characters.  If the cursor point is at the end of the line, then transpose the two characters before the cursor point.  Negative arguments are invalid.

transpose-words (M-t)
     Interchange the word before the cursor with the word at the cursor and position the cursor after both words.

upcase-word (M-u)
     Change the current (or following) word to uppercase and put the cursor after the word.  When given with a negative argument, the previous word is changed to uppercase, but the cursor point is not moved.

downcase-word (M-l)
     Change the current (or following) word to lowercase and put the cursor after the word.  When given with a negative argument, the previous word is changed to lowercase, but the cursor point is not moved.

capitalize-word (M-c)
     Capitalize the current (or following) word and put the cursor after the word.  When given with a negative argument, the previous word is capitalized, but the cursor point is not moved.

Deleting and Restoring Text
---------------------------

Here are the readline commands involved in deleting text and restoring previously deleted text.

In the following table, the term kill means to delete text from a line, but save that text in a buffer for later retrieval. Usually you retrieve killed text by yanking it back into the line.  The term yank means to retrieve text from a buffer and insert it at the cursor in the current line. Text that is deleted rather than killed is not saved and cannot be yanked back.

delete-char (C-d)
     Delete the character under the cursor. Note: If the cursor is at the beginning of the line, there are no characters in the line, and the last character typed was not C-d, then C-d means end-of-file return EOF, and BASH exits.

backward-delete-char (DEL)
     Delete the character behind the cursor.  A numeric argument given with this command causes the characters to be killed instead of deleted.

kill-word (M-d)
     Kill the text from the current cursor position to the end of the current word or, if between words, to the end of the next word.

backward-kill-word (M-DEL)
     Kill the text from the current cursor position to the start of the current word or, if between words, to the start of the previous word.

kill-line (C-k)
     Kill the text from the current cursor position to the end of the line.

backward-kill-line ()
     Kill backward to the beginning of the line.  That is, kill the text from the beginning of the line to the current cursor position.  This is normally not bound to a key.  (See unix-line-discard, which is bound to C-u.)

unix-line-discard (C-u)
     Kill backward to the beginning of the line. This is identical to backward-kill-line.

unix-word-rubout (C-w)
     Kill the text from the current cursor position to the previous whitespace.  This is different from M-DEL because the word boundaries are different.

yank (C-y)
     Restore the most recently killed text back into the line at the cursor.

yank-pop (M-y)
     Restore the next to most recently killed text back into the line at the cursor.  You can do this only if the prior command was C-y or M-y.

Manipulating the Command History
--------------------------------

Here are the readline commands for manipulating the command history (see History List).

accept-line (RET, newline character)
     Accept the line regardless of where the cursor is.  If this line is not empty, add it to the history list.  If this line was a history line, then restore the history line to its original state.

previous-history (C-p)
     Move up through the history list.

next-history (C-n)
     Move down through the history list.

beginning-of-history (M-<)
     Move to the oldest line in the history list.

end-of-history (M->)
     Move to the most recent line in the history list.

reverse-search-history (C-r)
     Search backward starting at the current line and moving up through the history as necessary.  This is an incremental search.

forward-search-history (C-s)
     Search forward starting at the current line and moving down through the the history.  This is an incremental search.

Specifying Numeric Arguments
----------------------------

Here is how you specify numeric arguments in readline:

digit-argument (M-0, M-1, ... M--)
     Add this digit to the argument already accumulating, or start a new argument.  M-- (meta-minus) starts a negative argument.

universal-argument ()
     This lets you type numeric argument digits without metafying. To start a negative argument use the minus key. A minus sign alone, with no other digits following, means -1.

     This is normally not bound to a key.

     Assume you have bound C-u to universal-argument.  Then C-u followed by a character that is neither a digit nor a minus sign means ``multiply the next argument by 4''.  C-u C-u means multiply the next argument by 16.

Completion: Letting readline Type For You
-----------------------------------------

You can save typing by asking for completion of the word you are in the midst of typing.  The system can complete partially-typed file names, command names, variable names, user names, and host names.  You can either specify the type of completion you would like to perform on the text before the cursor, or you can let the system guess what kind of name is being typed and complete it accordingly.

complete (TAB)
     Try to complete the text before the cursor

     In particular,

       * variable

          If the word before the cursor starts with $, try to complete it as a variable name.

       * user

          If the word before the cursor starts with ~, try to complete it as a user name.

       * host

          If the word before the cursor starts with @, try to complete it as a host name.

       * command

          If the word before the cursor is the first word in the command line, try to complete it as a command name.

       * file

          If none of the above cases apply, try to complete the word before the cursor as a file name.

possible-completions (M-?)
     List the possible completions of the text before the cursor. See above for what kind of completion is assumed.

complete-variable (M-$)
possible-variable-completions (C-x $)
complete-username (M-~)
possible-username-completions (C-x ~)
complete-hostname (M-@)
possible-hostname-completions (C-x @)
complete-command (M-!)
possible-command-completions (C-x !)
complete-filename (M-/)
possible-filename-completions (C-x /)
     Each of these specify the type of completion you would like to perform on the text before the cursor, whether it be filename, username, hostname, variable name, or hostname completion, respectively.  These BASH-specific readline commands do not depend on a prefix character; though, if one is there, such as the dollar sign, $, at the beginning of variable names, the commands will still work.

     The possible-...-completions commands are similar in functionality to the possible-completions command.

     Note that the specific completion commands are specific to BASH and are not defined in the readline library.

Some Miscellaneous Commands
---------------------------

clear-screen (C-l)
     Clear the screen, leaving the current line at the top of the screen.

abort (C-g)
     Sounds the warning bell and stops whatever was happening when you typed these keystrokes. For example, C-g can be used to abort entry of a numeric argument (see Numeric Arguments) or a search through command history (see History Commands).

do-uppercase-version (M-a, M-b, ...)
     Run the command that is bound to the named, but uppercase, command.

prefix-meta (ESC)
     Metafy the next character that you type.  This is for people without a META key.  ESC f is equivalent to M-f.

undo (C-_)
     This is the incremental undo.  Undo the last thing that you did. You can undo all the way back to an empty line.

revert-line (M-r)
     Undo all changes made to this line.  This is like typing the ``undo'' command enough times to get back to the beginning of your corrections for that line.

Customizing readline
====================

You can customize programs that use readline by putting commands in a readline initialization file, named .inputrc, in your home directory. When a program (such as BASH) that uses the readline library starts up, it checks the file ~/.inputrc to set up its key bindings and other parameters to your liking.

You can also force the initialization file to be reread (for example, if you modify it and want to use your modifications in BASH without logging out and logging in again) by typing C-x C-r (the default key binding for readline's re-read-init-file function.

Three kinds of lines can appear in this initialization file:

  bullet comment

     A line starting with # is a comment.

  bullet key binding

     See Readline Key Bindings.

  bullet variable setting

     See vi mode. See Readline Variables.

Key Bindings
------------

Although the readline library comes with a set of Emacs-like key bindings, it is possible that you would like to use different keys.

To bind a readline function to a key, place a line of the form

     KEY-NAME: READLINE-FUNCTION

or

     KEY-NAME: READLINE-FUNCTION COMMENT

in the ~/.inputrc file. See Readline Commands, for the function names and their default key bindings. Any text after the READLINE-FUNCTION is considered to be a comment and is ignored. Key names are explained below.

For example,

     C-u:	universal-argument

or

     C-u:	universal-argument  used to be unix-line-discard

binds C-u (which is initially bound to unix-line-discard) to universal-argument (which is not bound to any key by default).

Key Names
=========

For the key name, you can use the name of the key combination, such as C-f.  The various ``words'' you can use to describe keys are:

Control-k
C-k
     Holding down the control key and pressing the k key.

Meta-k
M-k
     Holding down the meta key and pressing the k key. See Notation, for alternative ways of metafying a key.

Rubout
DEL
     The delete key.

Escape

ESC
     The escape key, or Control-[.

RETURN
     The enter (or return) key.

Space
SPC
     The space bar.

LFD
NEWLINE
     The Control-j key.

TAB
     The tab key.

Key Sequences
=============

You can also specify an arbitrary key sequence instead of a single key:

     KEY-SEQUENCE: READLINE-FUNCTION COMMENT

To do so, surround the sequence in double quotes.

If you want to use the C- or M- specifications inside double quotes, you need to precede it with a backslash (\).  You can also specify the escape character with \e.  Note that you cannot use the ``words'' listed above, only:

     "\C-k"
     "\M-k"
     "\e"

Macros
======

You can bind a key (or key sequence) to a key sequence instead of to a named function. To do so, instead of a function name, give the key sequence in double quotes. Keys in this sequence are named as explained above under ``Key Sequences''

vi mode in readline
-------------------

The readline library does not have a full set of vi editing functions, but it does contain enough to allow simple editing of a line.

To switch interactively between Emacs and vi editing modes, use the command M-C-j (toggle-editing-mode). To enter the vi-like editing mode directly, without starting in Emacs mode, place the command:

     set editing-mode vi

in your ~/.inputrc file.

When you enter a line in vi mode, you are already placed in ``insertion'' mode, as if you had typed an i.  Pressing ESC switches you into ``edit'' mode, where you can edit the text of the line with the standard vi keys.  Since vi is not an officially supported Free Software Foundation product, we won't explain the key bindings here.

Other readline Variables
------------------------

In addition to editing-mode (see vi mode), there are a number of other variables that can be set in ~/.inputrc to affect readline's behavior.

To set a variable, put a line of the form

     set READLINE-VARIABLE-NAME SETTING

in the initialization file.

The current readline variables are:

editing-mode
     specifies the default editing mode for the readline library.  You can specify either emacs-style or vi-style default key bindings.  The default is emacs-style key bindings. The meaningful settings of EDITING-MODE are:

     emacs

     vi
          See vi mode, for more information.

horizontal-scroll-mode
     determines how to display lines longer than the width of your display. The meaningful settings of HORIZONTAL-SCROLL-MODE are:

     Off
          If horizontal-scroll-mode is set to Off (actually, any value other than On is treated as Off), lines are ``wrapped'' when they extend beyond the width of the display. Such a line takes more than one line on the screen, but it still counts as a single line. (For example, C-a still goes to the very beginning.)

     On
          If horizontal-scroll-mode is set to On, the line is shifted to the left about a third of the display's width when the cursor extends beyond the right side of the display. That is, the input line is scrolled between the two edges of the screen so that the current part is visible, though other parts may not be.

     The default value of horizontal-scroll-mode is Off.

mark-modified-lines
     specifies whether or not to ``mark'' modified history lines with an asterisk, *. The meaningful settings of mark-modified-lines are:

     Off
          Modified history lines are not marked.

     On
          Modified history lines are marked.

     The default value of mark-modified-lines is Off.

A Sample ~/.inputrc file
------------------------

Here's an example of a simple readline customization file, ~/.inputrc:

     # -*- text -*-
     # File: ~/.inputrc
     # This file controls the behaviour of line input editing for
     # programs that use the GNU Readline library.  Existing programs
     # include Camera, Bash, and Gdb.
     #
     # You can re-read the inputrc file with C-x C-r.
     # Lines beginning with '#' are comments.
     #
     # Set various bindings for emacs_mode.

     Meta-Rubout:	backward-kill-word  Stuff after the function name ignored
     #Control-u:	universal-argument

     # Note that the order of the words doesn't matter.
     Meta-Control-r:	revert-line
     Control-Meta-u: revert-line
     C-Meta-T:	transpose-words
     M-C-k:		transpose-chars
     "\C-x\C-?":	backward-kill-line

     # This line is bad syntax. It should have the M- before the C-.
     # But it works.
     "\C-\M-f":	forward-word

     # Here is a macro definition.  You can tell because the right-hand
     # side is in quotes.
     #"\C-xr":	"\C-a\C-kemacs -f rmail\C-j\C-y"

     # Bind the arrow keys. (good for sun and vt220, vt100, etc.. )
     "\e[A":		previous-history
     "\e[B":		next-history
     "\e[D":		backward-char
     "\e[C":		forward-char

     # help key macro
     "\e[28~":	"\C-a\C-khelp | less\C-j\C-y"   VT220 help key
     "\e[3~":	delete-char			VT220 remove key
     # C-r is reverse-search-history
     "\e[1~":	"\C-r"				VT220 find key

     # Select the mode.
     set editing-mode emacs
     set horizontal-scroll-mode On

History Substitution
********************

BASH provides facilities to remember commands and let you reuse them.

The command-history features described here are not specially programmed into BASH. Rather, they are provided by the history library, which is used by a number of other GNU programs besides BASH. (In general, programs that use readline also use history.) This means that you can use the same history facilities with a variety of programs.

The history library maintains a list of recent command lines, or events. It provides you with functions for remembering lines on a history list, searching through the list for a line containing an arbitrary text string, and referencing any line on the list directly.  In addition, a history expansion function is available which allows you to easily use those command lines again as is, or with some modifications, with very little additional typing.

If you find using the history library too difficult, you can use the readline library instead (see Editing).  The readline library includes history manipulation by default, and has the added advantage of Emacs-style command line editing.

How to Use History Substitution
===============================

If you type the command history on a line by itself, you are presented with a list of events stored in the history list.  For example:

     bash$ history

          1   cd News
          2   ls
          3   ls -l
          4   more tobob.doc
          5   mail bob
          6   rm tobob.doc
          7   ls
          8   cat memo
          9   history

The events are numbered from the oldest command typed (in this case, number 1) to the latest command typed (in this case, number 9).

You can re-execute any event in a history list.  First you have to determine which line from the previous history to use, then you need to select portions of that line for inclusion in the current one.

The line selected from the previous history is called the event, and the portions of that line that are acted upon are called words.  The line is broken into words in the same fashion that the BASH shell does, so that text surrounded by quotes is considered to be one word (see Quotation).

Determining Which History Line to Use
=====================================

By far the most common use of this history substitution is simply to reuse an entire line.  One way this can be done is to enter a line which consists of ! followed immediately by enough characters to uniquely identify the beginning of the line you want to reuse.  For example, !cat re-runs the last cat process (cat memo) in the above history list:

     bash$ !cat
     cat memo
     This is a memo.
     bash$

Another way to reuse a line is to follow the ! with a number, which specifies which line in the history list to use.  For example, to reuse cat memo we could have typed:

     bash$ !8
     cat memo
     This is a memo.
     bash$

A third way is to type !?STRING, which says to look backwards through the history for the first line which contains STRING.  Here's yet another way of re-using cat memo:

     bash$ !?memo
     cat memo
     This is a memo.
     bash$

As we have just demonstrated, there are several ways to refer to an event:  you can use its relative position in the history list, its absolute position in the history list, or any text the event may contain.  Here is a table summarizing the various ways to refer to an event:

!!
     refers to the previous command.

!N
     refers to an event by its absolute position in the history list.  It refers to command line number N, where N is the line number shown by the history command.

!-N
     refers to an event by its relative position in the history list.  It refers to the command line N before the current line.

     For example:

          bash$ echo a
          a
          bash$ echo b
          b
          bash$ !-2
          echo a
          a
          bash$

     !-2 may be used to re-run the command prior to the last command entered.  Successive usage of !-2 may be used to cycle the last two commands.  In fact, the last N commands may be cycled through repeatedly by using !-N.

!STRING
     refers to the most recent command beginning with STRING.

!?STRING
!?STRING?
     refers to the most recent command containing STRING.  The closing ? is optional, and is necessary only when you need to separate the event designator from additional text.

     Here's an example.  Given the following two commands, entered in this order:

          bash$ cp /etc/motd ~
          bash$ rcp /etc/motd unsuspecting:/etc/motd

     !cp matches the first command, while !?cp matches the second command.

!#
!:#
     both refer to the current line so far.  For example:

          bash$ echo foo !#
          echo foo echo foo
          foo echo foo
          bash$

No matter which way you choose to refer to an event, the shell searches its history list from the most recent event to the least recent event, until it finds a match for your request.  If your request is too ambiguous, or if no such event exists, you are given an error message.

Whenever the shell sees the special character ! in a command line, it checks the history list and makes the appropriate substitution.  There are some exceptions:  if ! is followed by a SPC, TAB, RET, = or (, or preceded by < or |, history substitution does not take place.

Words Within Events
===================

It is possible to select and use only portions of an event.  You can select any word, or series of words, from an event.  Several words surrounded by quotes are considered to be one word.

The words of an event line are numbered from left to right, with the first word (the command name) being 0.  For example:

     bash$ echo one two three four five

In this example, word 0 is echo, and word 5 is five.

To specify a particular word from a previous event, follow the event specification with a colon, :, and a designator for the desired word, or words, from that event.  The word designators are:

0
     The number 0 represents the first word, which is almost always the command name.

N
     This matches the N'th word.

^
     This is a special notation representing the first argument (that is, word 1).

$
     This is a special notation representing the last argument.

%
     This represents the word matched by the most recent pattern search, ?STRING[?].

X-Y
     This matches a range of words.

-Y
     This is equivalent to the range 0-Y.

*
     This matches all the words after word 0, up to and including the last word.  This is similar to matching the range ^-$, except * can match 0 or more words, while ^-$ must match 1 or more words.

X*
     This is equivalent to the range X-$.

X-
     This is equivalent to the range X-($-1).

The : that separates the event specification from the word designator can be omitted if the word designator begins with a ^, $, * or %. When referring to the immediately preceding command, you can omit the line identifier if you want. Therefore, !:2 refers to word 2 in the previous command line.

Note that ! alone on a line means nothing in terms of history expansion.  Also, if an event contains more than one command line separated by semicolons, the semicolons count as words too.

Here are several examples using the various word designators in the above table:

     bash$ mkdir /nfs/cwjcc/fs2/src/Gnu/src/bash/1.06
     bash$ mv bash.tar.Z !$
     mv /nfs/cwjcc/fs2/src/Gnu/src/bash/1.06
     bash$ cd !$
     cd /nfs/cwjcc/fs2/src/Gnu/src/bash/1.06

This example uses the shorthand for the last word on a command line to avoid typing in a lengthy path name more than once.

     bash$ echo a
     a
     bash$ !! b
     echo a b
     a b
     bash$ !! c
     echo a b c
     a b c
     bash$ echo !*
     echo a b c
     a b c

This example demonstrates how you can build up a command line with successive applications of the !! notation.  You then use the !* expansion to make use of all arguments accumulated so far.

     bash$ cc -o prog -g a.c b.c c.c
     bash$ cmd=!:0 output=!:2 optimize=!:3 files="!:4-$"

This shows one possible use of the history facilities to break up command lines into individual elements.  After the second command, the individual portions of the command may be reused, perhaps to print the source files just compiled with lpr $files.

Modifying Previous Events
=========================

Sometimes you don't want to re-execute an event exactly. Perhaps you mis-typed a file name, or want to substitute a new pathname, or a different argument.  Whatever the reason, you can modify an event, or any word of an event, by following that event with a colon, :, and a modifier.

Here is a list of modifiers and their explanations:

h
     This removes the last element of a pathname, leaving the only the head.

r
     This removes a filename extension, or trailing suffix .XXX, leaving only the root.

e
     This removes all but the filename extension, or trailing suffix .XXX.

t
     This removes all of the leading pathname components, leaving only the tail.

s/STRING1/STRING2
     This substitutes the value of STRING2 for STRING1 the first time it appears.  If the g flag is given as well, the changes take place globally; that is, all occurrences of STRING1 are replaced with STRING2.

p
     This prints the new command but does not execute it.  This allows you to preview the effects of modifiers safely.

s/THIS/THAT
     substitutes the first occurrence of THIS with THAT on the specified history line.

gs/THIS/THAT
     globally substitutes THIS with THAT on the specified history line.

The modification is applied only to the first applicable word on the line.  If there are two or more occurrences on that line, the subsequent occurrences are not changed.  If no word on the line is applicable, then you get an error message.

Here are some examples of reusing command lines with slight modification:

     bash$ diff -c2 old/shell.c shell.c > shell.diffs
     bash$ !!:gs/shell/builtins
     diff -c2 old/builtins.c builtins.c > builtins.diffs

This example demonstrates the use of the substitution mechanism to re-run a command.  This example may be used repeatedly to create ``diffs'' of a number of changed files without retyping the lengthy command each time.

     bash$ echo /a/b/c/d
     bash$ head="!:1:h" tail="!:1:t"
     bash$ echo $head $tail
     /a/b/c d

This shows a possible use for the filename splitting facilities.

     bash$ edit file.c
     bash$ f="!:1:r" ; echo making ${f}.o ; make ${f}.o ; unset f

This is a rather clumsy way to remake an object file from a just-modified source file.  While this example shows the use of the history library, there are easier ways to remake an object file.  For example you can encapsulate the echo and make into a function, like this:

     bash$ type make_o
     make_o is a function
     make_o ()
     {
          echo making ${1}.o
          make ${1}.o
     }
     bash$ edit file.c
     bash$ make_o !:1:r
     make_o file

Shortcuts
=========

A ^ at the beginning of a command line is a special way to designate that you want to make changes, or corrections, to the previous command line.  In this case, ^ is equivalent to !:s^, and provides a convenient and special shorthand for making substitutions to the (immediately) preceding event.  The syntax for this substitution is:

     ^OLD^NEW

The OLD characters between the two ^ are replaced by the NEW characters following the second ^.  For example:

     bash$ mroe parse.y
     bash: mroe: command not found
     bash$ ^mroe^more

The first command contained a spelling error, resulting in an unknown command.  Using the quick substitution feature, we can rerun the command with the correct spelling substituted.

Delimiters
==========

You can delimit a history substitution from the characters that follow it by surrounding that substitution with {and }.  For example:

     bash$ make flags.o
               [ errors compiling flags.c ]
     bash$ edit {!$:r}.c

In the above example, we attempt to use the make command to create flags.o from flags.c.  There are errors in flags.c, so history substitution is used to create the name of the source file so that it can be edited.

While braces are not strictly necessary in this example, note that the braces are not treated specially by the history substitution mechanism in any way.  This works because brace expansion is enabled on our version of BASH.  If brace expansion is not enabled, enclosing a history substitution in braces will cause those braces to be retained.

Preventing Shell Interpretation of Special Characters
*****************************************************

There are times when you want the shell to treat special characters as regular characters, and not expand or interpret them. To do this, you must quote the special character by preceding the character with a \ or by surrounding the character (or part of the argument containing it) with single or double quotes.

\
     The backslash, \, forces the character that follows it to have its literal meaning, suppressing any special interpretation in the shell. Exception: A backslash followed by a newline character signifies a continuation of a shell command line onto the following line (see Continuation).

     Note that the backslash protects a single character, not a string of characters.

     For example, rm bad*name deletes all files whose names start with bad and end with name, whereas rm bad\*name deletes only the file named bad*name.  The \ prevents the shell from interpreting the * as a wildcard.

     You can protect the backslash itself from being interpreted by the shell by preceding it with another backslash.

'...'
     Single quotes turn off the special meanings of every character between them.  All these characters are taken literally.  This allows you to include blank characters in a string.  For example:

          'This $#?!!# sentence is taken literally.'

     Note that even the backslash character is treated literally between single quotes.  Therefore, there is no way to include single quotes themselves in the string.

"..."
     Double quotes turn off the special meanings of every character between them except $, ', and \.  The characters $ and ' retain their special meanings within double quotes.  When surrounded by double quotes, the backslash, \, retains its special meaning only when followed by $, `, ", \, or the newline character.

     For example:

          "The value of test is $test."

     You can protect a double quotation mark from being interpreted by the shell by preceding it with the backslash character, as in \". A double quote may be quoted within double quotes by preceding it with a backslash.

     Warning: the special parameters $* and $@ have special meanings when inside double quotes (see Predefined).

You should quote any special character if you do not want the shell to use that character's special meaning. Therefore quote all redirection operators, wildcard characters, command-line characters, quote characters, and grouping characters if they are to represent themselves.  In particular, the following characters should be quoted if they are to represent themselves:

       !  |  &  ;  <  >  (  )  $  `  '  "  \  *  ?  [  ]  #

In addition, you should always quote the space, tab, and newline characters if they are not to be interpreted by the shell.  You can use single or double quotes around an entire argument or word, or around just part of one.  For example:

     make CC="cc -O"

shows how to specify cc -O as the compilation command.

Redirecting Input and Output (Advanced)
***************************************

Redirection Using File Descriptors
==================================

The basic redirection operations (see Redirection) are actually special cases of a more general mechanism for affecting the input and output files used by programs.

Programs actually do their input and output in terms of file descriptors (non-negative integers) that are associated with files or devices. For example, a program might read from file descriptor 3 and write to file descriptors 6 and 8. The redirection operators are a means of associating open files with file descriptors, so that such a program will use the desired files.

In order for the shell to be able to set up command input and output in simple, general ways -- hooking commands together with pipes (see Pipes) or redirecting input and output to files as shown earlier (see Redirection) -- certain conventions have been established for file descriptors.  Descriptors 0, 1, and 2 are generally used as follows:

0
     is called standard input. Programs usually read their input from standard input.

1
     is called standard output. Programs usually write their output to standard output.

2
     is called standard error. Programs usually write their error messages to standard error.

Other file descriptors have no standard meaning.

You can redirect any file descriptors you like, but not all redirections make sense.  In particular, redirecting a file descriptor number that the program doesn't use will have no effect.

In general, a redirection using file descriptors looks like this:

     COMMAND [N]REDIRECTION-OPERATOR M
     or
     COMMAND [N]REDIRECTION-OPERATOR FILE

where N (which is optional) and M are file descriptors, FILE is a file, and the REDIRECTION-OPERATOR is as described below.

Warning: If N is supplied, there must not be any space between it and the operator.

If the file descriptor N is omitted and the first character of the redirection operator is <, N defaults to the standard input (file descriptor 0).  If N is omitted and the first character of the redirection operator is >, the N defaults to the standard output (file descriptor 1).

N> FILE
N>| FILE
N>> FILE
     open FILE for output on file descriptor N. N defaults to 1 (standard output). Thus the operators >, >|, and >> described earlier, which redirect standard output, are equivalent to 1>, 1>|, and 1>> respectively.

       * If FILE doesn't yet exist, it is created.

       * If FILE already exists:

            * With > and >|, FILE is erased before the first output is written to it.  Be careful: If a file of the same name already exists, its contents are deleted before your command's output is written to that file. If you don't want > to erase existing files, set the shell's noclobber variable; then > with an existing file will generate an error message and leave the file alone.  (But note that >| will clobber existing files regardless of the setting of the noclobber variable.)

            * With >>, the output is appended to the end of an existing FILE.

     For example:

          bash$ find / -name resume -print 2> /dev/null

     This command looks for and prints the pathnames of all files named resume by traversing all directories under the / directory.  When find encounters permission problems (for example, directories it does not have permission to read) it prints an error message on standard error.  The above redirection 2> /dev/null forces all these error messages to be written to the special file /dev/null, which simply discards these messages so that only the requested resume files are printed on standard output. This saves you from wading through pages of uninteresting error messages from find.

N< FILE
     opens FILE for input on file descriptor N. N defaults to 0 (standard input). Thus the operator < described earlier, which redirects standard input, is equivalent to 0<.

N<> FILE
     opens FILE for both reading and writing on file descriptor N. N defaults to 0 (standard input).

     As with > (above), an existing FILE is erased before the first output is written to it unless the shell's noclobber variable is set (in which case <> with an existing file will generate an error message and leave the file alone.)

N>& M
     makes the file descriptor N be a copy of the file descriptor M. N defaults to 1 (standard output).

     Thus the redirection >&FILE described earlier, which redirects standard output and standard error to the FILE, is equivalent to >FILE 2>&1.

     For example :

          bash$ make >make.log 2>&1

     make produces output both on the standard output (as it executes commands) and on the standard error (in the case that a file didn't compile correctly, etc.). The first redirection operator on the line says to send output for the standard output into a file called make.log. The second redirection causes output to file descriptor 2 (the standard error) to be output wherever the output from file descriptor 1 is going (the standard output). Thus, both the standard error and standard output are written to make.log.  (There is a shorthand for redirecting both the standard output and the standard error to a single file. See Redirection, >&FILE.)

N<& M
     makes the file descriptor N be a copy of the file descriptor M. N defaults to 0 (standard input). (Note that N<& M and N>& M behave identically except when N is omitted, in which case they have different defaults.)

[N]>&-
     closes the file descriptor N. N defaults to 1 (standard output).

[N]<&-
     closes the file descriptor N. N defaults to 0 (standard input). (Note that [N]<&- and [N]>&- behave identically except when N is omitted, in which case they have different defaults.)

Multiple Redirections
=====================

More than one redirection operator can appear in a command. The order in which redirections are specified is important. The shell evaluates redirection operators in the order encountered, from left to right.  A file descriptor specified with an earlier redirection operator can be used by a subsequent redirection.  For example:

     ls > error-list 2>&1

redirects first the standard output (>) and then the standard error (2>&1) to the file error-list, while the command:

     ls 2>&1 > error-list

redirects only the standard output to the file error-list.  The first redirection operator 2>&1 makes the standard error (2) be a copy of the standard output (1) before the standard output is redirected to error-list with >.

Redirection in Pipelines
========================

Each command in a pipeline may include redirection operators.  These redirections are performed after the pipes that link the commands are created. That is, first the standard input and standard output of each command in the pipeline are set up as specified by the pipes, then any redirections specified in the commands are performed. Thus such a redirection can access the standard input and output set up by the pipeline.  For example, 2>&1 in the first command in a pipeline makes that command's standard error be the same as its standard output, hence sends the command's error messages along with its ordinary output to the second command in the pipeline.

Redirection to Shell Scripts
============================

In general, such a redirection of input looks like this:

     COMMAND REDIRECTION-OPERATOR WORD

where the REDIRECTION-OPERATOR is as follows, and spaces surrounding it are optional:

<<
     instructs the shell to read input for COMMAND from the same place as the shell is reading commands from. The shell reads lines until a line containing only the given WORD (with no trailing blanks) is seen.  All of the lines read up to that point are considered the input for the COMMAND. For example:

          bash$ sort << foo
          hip
          hip foo
          hooray
          and
          foo
          and
          hip
          hip foo
          hooray
          bash$

     The four lines after sort << foo became the input to the sort command.  The fifth line, containing foo on a line by itself, marked the end of the input.  (Note that the foo in the second input line did not end the input because the line contained other text as well.)  The four lines after the end of the input are the output of the sort, namely the input lines in alphabetical order.

<<-
     <<- is like <<, except that leading tab characters are stripped from each line of input as it is read.

Grouping Commands
*****************

{ LIST; }

     Curly braces are used to group commands.  The list of commands is executed in the current shell environment.  The curly braces must either begin a line, follow a ;, or be surrounded with whitespace for the shell to recognize them as grouping commands.  For example:

          bash$ foo=bar
          bash$ { ls -l ; echo "Listing finished."; echo $foo } >listing

     lists the files in the current directory, outputs ``Listing finished.'', and outputs ``bar'', all of which is redirected into the file listing.  Unlike the following example, the grouping commands do not start a subshell, so the current shell's variables are available for use.

(LIST)
     The list of commands is executed in a subshell.  Variable assignments and built-in commands that affect the shell's environment do not remain in effect after the command finishes.

     The fact that commands within parentheses are executed within a subshell means that the parent shell is unaffected by shell side-effects of those commands.  Changes in shell state caused by commands executed in a subshell do not affect the parent shell.

     Let's illustrate:

          bash$ pwd
          /home/alan/work
          bash$ (cd ..)
          bash$ pwd
          /home/alan/work
          bash$ cd ..
          bash$ pwd
          /home/alan
          bash$

     In this example, the current working directory is /home/alan/work as shown by the output of the pwd command.  The command (cd ..) executes in a subshell so that it does not change the current directory of the parent shell and the user remains in the original directory, /home/work/alan.

     However, when the command cd .. is executed in the parent shell (that is, it is executed without being surrounded by parentheses) the parent shell's current working directory is changed to /home/alan.

Aliases
*******

Aliases are a way to rename, redefine, or otherwise rearrange commands to your liking.  An alias is created using the following syntax (note that there cannot be any spaces before or after the = sign):

     alias NAME=EXPANSION

The NAME is the command-name shorthand you want to enter at the shell prompt.  The EXPANSION is the command that the NAME will stand for.  For example:

     alias more=less

causes the program less to be substituted for the operating system's more program every time the word more is typed.

If the last character of the value for the alias, EXPANSION, is a blank, then the word following the alias will also be checked for substitution.  For example:

     alias time='time '

allows you to time a command for which you have defined an alias. With this alias you can time what you would be running if you typed the expanded version as a command.

For example, let's say you defined an alias alias more=less. Normally, if you type time more, more is timed.  However, if the time alias has been previously defined, typing time more times less, which is what you want.  The alias more is expanded, and its value (less) is substituted as the program to time.

If the value for the alias, EXPANSION, contains spaces, tabs, or metacharacters, you must enclose that definition in quotes to avoid misinterpretation by the shell.  For example, let's say that you use the command-option sequence ls -la at lot.  You can assign this command to the alias la to make typing quicker and easier:

     alias la='ls -la'

Now you can type la instead of ls -la when listing files.

To get a list of all the currently defined aliases, simply type the alias command with no arguments.  A list of aliases in the form NAME=VALUE is displayed on the standard output.  If you want to know if a specific shorthand name has any aliases, you can type:

     alias NAME

This tells you if any aliases exist for that specific NAME.

Aliases are local to the shell in which they were declared.  This means that aliases can't be used within shell scripts unless those aliases were declared in that script.  This means that the alias command has to be executed in the shell script before the command which references that alias is read. It also means that aliases disappear when their shell is terminated. BASH aliases cannot be exported to another shell.  To get BASH to remember an alias permanently, you have to enter that alias in your login file (see Start-up).

Creating Aliases For Complex Commands
=====================================

While you can use simple string substitution with aliases, note that the alias command is limited to expanding only the first word in a command.  Using pipes, |, semicolons, ;, && (AND) and || (OR), it is possible to have more than one command sequence per command line. In this case, you can have more than one alias on the command line, but you can still only have one alias per command.  For example, let's create two more aliases:

     bash$ alias listdir='ls'
     bash$ alias linecount='wc -l'

and combine those aliases on one command line:

     bash$ listdir | linecount

The alias command expands listdir to ls and linecount to wc -l because listdir and linecount begin separate commands.

If you need more complicated expansion in a command line, use a shell function (see Functions).  In particular, there is no mechanism in BASH for using arguments in the replacement text of aliases.  If arguments are needed, a shell function should be used instead of an alias.

You can also make aliases that represent multiple commands.  For example, you can create an alias that goes to a directory of your choice (cd), lists what is in that directory in long form (ls), and shows you the total disk space used by that directory (du):

     alias m-use='cd /usr/spool/mail; ls -la; du'

To use this alias, just type m-use.

Lastly, you can alias keywords.  For example, if you would rather end the do part of a loop command (see Conditionals and Loops) with od than with the normal done, you can

     bash$ alias od=done
     bash$ for i in 1 2 3
     > do
     > echo $i
     > od
     1
     2
     3

Removing Aliases
================

To get rid of aliases, use the unalias command.  This command looks like this:

     unalias NAME1 NAME2 ... NAMEN

The unalias command removes all the named aliases from the list of defined aliases.  For example:

     unalias m-use

removes the m-use alias, if present.

Shell Variables
***************

Mechanics of Named Variables
============================

Shell behavior that depends on a variable may depend on:

  * the value of the variable

  * whether the variable exists (is set), independent of what value it has

Thus, in order to configure a shell variable to get the effect you want, you may need to know:

  * how to tell whether a variable exists (is set)

  * how to create (set) a variable

  * how to unset a variable (make it cease to exist)

  * how to find out the value of a variable

  * how to change the value of a variable

To find out the value of a variable, type echo $NAME, where NAME is the variable of interest. (Be sure to include the $:  If you omit it, echo just repeats the NAME itself.)

  * If something is printed, that is the value of the variable.

  * If nothing is printed, then either the variable exists and has a null (invisible) value, or the variable does not exist.

More generally, to get the value stored in a variable, precede the variable's name by a dollar sign, $.

To set a variable (create a new variable or change the value of an existing variable), type NAME=NEW-VALUE, where NAME is the variable you want to set and NEW-VALUE is the value you want it to have. Don't leave any blank space around the =. If you just want to create the variable, and don't need to give it any particular value, you can simply omit the NEW-VALUE and type NAME=.

The name of a shell variable must start with a letter or an underscore and it can contain only letters, digits, and underscores. Uppercase and lowercase letters are not equivalent in names. Be careful to type variable names correctly: If you type a name wrong before an =, you will either change the wrong variable or create a new variable.

To include whitespace (spaces, tabs, or newline characters) in a variable's value, either quote the value with "..." or '...', or precede each whitespace character with a backslash, \ (see Quotation).

To get rid of a variable, type unset NAME, where NAME is the variable of interest.

To find out whether a variable exists, you can do any of the following:

  * Type set to get a listing of all your shell variables in alphabetical order, and see if the variable is in the list.

  * Type set | grep NAME=. If the variable NAME exists, its name (and value, if non-null) will be given; otherwise there will be no output.

  * Type set -u to tell the shell to make echo of an unset (nonexistent) variable give an error message. From then on, echo $NAME will be different for nonexistent variables than for variables with null values.

Warning: set and unset are not inverse commands: Although unset unsets shell variables, set does not set them.

Examples with Named Variables
-----------------------------

Here are some examples of user-defined variables:

     bash$ test=This\ is\ a\ test
     bash$ test_2="This is also a test"
     bash$ test_3='Yet another test'
     bash$ echo $test
     This is a test
     bash$ echo $test_3
     Yet another test

To prevent $ from meaning ``evaluate the following variable,'' precede the $ with a backslash, \, or enclose $ and the reference in single quotes. For example:

     bash$ echo \$test
     $test
     bash$ echo '$test'
     $test
     bash$ echo $test
     This is a test

Positional Parameters
=====================

A program, shell function, or shell script needs a way to refer to arguments passed to it on the command line that invoked it.  The shell provides for this by means of special variables called positional parameters.

The name of a positional parameter is a positive integer.

The value of a positional parameter is whatever the shell assigns it from a command line, or whatever you assign it with set or shift (described below).

To evaluate a positional parameter, precede its name by a dollar sign, $, just as you would a named variable. But if the parameter name is longer than a single digit, you must enclose it in braces.  For example, you'd type ${10} to refer to the value of parameter 10.

When you give a command, the arguments are put into consecutive positional parameters starting with 1.

For example, assume we have a script named args that simply echoes its first two arguments to the standard output. That is, the script contains just the command echo $1 $2.  Then args behaves as follows:

     bash$ args 1 3
     1 3
     bash$ args hi there
     hi there
     bash$ args hi there everybody
     hi there
     bash$

See Predefined, for information about the parameter 0, which holds the name of the current command, the parameters * and @, which refer to all the positional parameters at once, and the parameter #, which holds the number of positional parameters (the current number of arguments).

The set command can be used to assign new values to positional parameters.  The command

     set VALUES

assigns the given VALUES to consecutive positional parameters starting with 1.  For example, if we augment the above args script to be

     echo $1 $2
     set new message
     echo $1 $2

then it will modify its positional parameters, replacing the command-line arguments with new and message, and will behave as follows:

     bash$ args hi there everybody
     hi there
     new message
     bash$

The shift command moves each positional parameter's value into the parameter to its left. The value of 2 is moved into 1, the value of 3 is moved into 2, and so on. The last parameter becomes null.

This is useful, for example, in a recursive shell function, to ``cdr down'' the list of arguments.

shift can also take a numeric argument:

     shift N

This causes the positional parameters to be shifted left N positions instead of just 1 position. The value of parameter N+1 is moved into 1, and so on.

For example, if we modify the above args script to be

     echo $1 $2
     shift 2
     echo $1 $2

then it will behave as follows:

     bash$ args hi there everybody else
     hi there
     everybody else
     bash$

BASH itself also has positional parameters, which you can set, shift, and examine. The positional parameters seen by a command are distinct from those of the invoking shell. In this example, we set the shell's first three positional parameters and see that they are unaffected by execution of the args command defined above, which uses echo $1 $2 to echo its first two arguments.

     bash$ set one two three
     bash$ echo $1 $2
     one two
     bash$ args hi you
     hi you
     bash$ echo $1 $2
     one two
     bash$

The set command is the easiest way to break a multi-word string into elements that can be referenced individually.  This can be useful in conjunction with command substitution (see Command Subs).  For example, we can set the positional parameters to the words in the output of the date command as follows:

     bash$ set $(date)
     bash$ echo $1 $2 $3 $4 $5 $6
     Fri Feb 22 18:13:14 EST 1991

Predefined Shell Variables
==========================

The predefined shell variables are set by the shell. You cannot assign them values, but you can reference their values by prefacing their names by $. The predefined shell variables are:

?
     contains the exit status returned by the command that was last run in the foreground.

!
     contains the process identification number of the last background command.

$
     contains the process identification number of the current shell.

#
     contains the current number of positional parameters (see Positional).

-
     contains shell options.

0
     (zero) contains the name of the command being executed.

*
@
     contain a list of the positional parameters.

     * and @ are equivalent unless they appear inside double quotes. $* $@ are both equivalent to $1 $2 ... $N, where N is the last positional parameter. But "$*" is equivalent to "$1 $2 $3 ..." and "$@" is equivalent to "$1" "$2" "$3" .... In other words, "$*" expands to a single word, whereas "$@" expands to separate words.

          bash$ cat a
          this is a file named a
          bash$ cat b
          this is a file named b
          bash$ cat c1
          /bin/cat "$*"
          bash$ cat c2
          /bin/cat "$@"
          bash$ c1 a b
          a b: No such file or directory
          bash$ c2 a b
          this is a file named a
          this is a file named b

     This example shows the use of two scripts: c1, which tries to execute /bin/cat on the expansion of $*, and c2, which executes /bin/cat on the expansion of $@.  When invoked with more than one argument, c1 attempts to run cat on the file whose name is the concatenation all its arguments -- not what you would expect. On the other hand, c2 uses $@ and behaves correctly.

The following example sets the positional parameters to the output of the date command and shows that that output consists of 6 words:

     bash$ echo $#
     0
     bash$ set $(date)
     bash$ echo $#
     6
     bash$ echo $*
     Sat Aug 4 22:19:05 EDT 1990

Here's an obscure script using predefined parameters:

     #
     # 2, 3, 4, 5 -- print in the number of columns defined by the
     # name of the script.  Adapted from Kernighan and Pike.
     #
     /bin/pr -$(basename $0) -t -l1 "$@"

This file prints its input in as many columns as specified by its name -- if invoked as "2", it prints its input in two columns.

Variable Substitution
=====================

The simplest case of variable substitution is the simple $NAME construct, in which the value of the variable NAME is substituted for $NAME. More complicated constructs let you specify what should happen if the named variable is unset or if its value is null.

BASH's parameter substitution facility lets you test and conditionally set the value of parameters and shell variables. Braces allow a variable to be tested to see if it is defined and is not the null string.  This is important as sometimes the value of an expression depends on whether or not a variable has been defined.  If the colon in the following expansions is omitted, BASH only tests that the parameter is unset; it does not test to see that it's unset or null.

The substitutions allowed are:

${VARIABLE}
     The value of VARIABLE is substituted.  The braces are required when VARIABLE is a positional parameter with more than one digit, or when VARIABLE is followed by a character that isn't part of its name.

${VARIABLE:-STRING}
     If the named VARIABLE exists, then the expression has the value of the variable, otherwise it has the value STRING. For example:

          echo ${timenow-$(date)}

     This echoes the current time, as stored in the variable timenow. If timenow isn't set, the date command is run to generate it.

${VARIABLE:=STRING}
     If the named VARIABLE exists, then the expression has the value of the variable, otherwise it has the value of STRING and STRING is assigned to VARIABLE.  For example:

          bash$ echo $A

          bash$ echo ${A=123}
          123
          bash$ echo $A
          123

     The first line of this example shows that A is unset. The second line assigns the value of 123 to A.  Then the value of $A is substituted, so A retains the value 123.

     This form does not work with positional parameters (see Positional) or special parameters (see Predefined).

${VARIABLE:+STRING}
     If the named VARIABLE exists, then it has the value of STRING, otherwise it has no value. For example:

          if [ "${var+set}" = "set" ] ; then
               echo '$var' is set
          fi

     This example shows a simple method to test whether or not a shell variable is set.  If var has a value, then the expansion has the value set, and you can test on that fact.

${VARIABLE:?TEXT}
     If the named VARIABLE exists, then the expression has the value of the variable, otherwise the message TEXT is printed. For example:

          : ${REQUIRED?"REQUIRED must be set"}

     This statement echoes REQUIRED must be set if REQUIRED is not set. This can be used to inform the user that further execution of the current script is not possible.  If you don't make this part of an interactive script, the shell exits after printing the message. If there is no TEXT following the ?, BASH prints a standard message.

${#VARIABLE}
     The length in characters of the value of VARIABLE is substituted. If VARIABLE is * or @, the length substituted is the length of * expanded within double quotes.

${VARIABLE#STRING}
${VARIABLE##STRING}
     The STRING is expanded to produce a pattern just like pathname expansion.  If the pattern matches the beginning of the value of VARIABLE, then the expansion is the value of VARIABLE with the shortest matching pattern deleted (the # case) or the longest matching pattern deleted (the ## case).

${VARIABLE%STRING}
${VARIABLE%%STRING}
     The STRING is expanded to produce a pattern like pathname expansion.??? If the pattern matches a trailing portion of the value of VARIABLE, then the expansion is the value of VARIABLE with the shortest matching pattern deleted (the % case) or the longest matching pattern deleted (the %% case).

Shell Functions
***************

A shell function stores a series of commands for execution at a later time, similar to a shell script.  Functions are executed in the current shell; no new process is created to interpret them.

Defining a Function
===================

Function definitions can be entered from the command line or declared in your login file (see Start-up). The shell doesn't save functions when you log off.  To make function definitions ``permanent'' you must enter them in your login file (see Start-up). To declare a function use either of the following equivalent forms:

     function FNAME () { COMMANDS }

     or

     FNAME () { COMMANDS }

It makes no difference which form you use.  Both create a simple command invoked by FNAME which executes the given COMMANDS.

A function can be recursive; that is, it can call itself.  No limit is imposed on the number of recursive calls that can be made.  However, make sure you put in checks to avoid infinite recursion, as you would in any programming language.

Function Arguments
------------------

Arguments present on the command line along with FNAME are passed to the function as positional parameters during its execution (see Positional).  The special parameter # is updated to reflect the change.  Positional parameter 0 is unchanged.  When the function finishes, the values of the positional parameters and the special parameter # are restored to the values they had before the function was executed.

Here's an example of a function, using the first syntax:

     function xtitle()
     {
        if [ "$DISPLAY" ] ; then
        echo -n -e "\033]2;$*\007";
        echo -n -e "\033]1;$*\007";
        fi
     }

If BASH is executing in an xterm window, this function makes its arguments be the string displayed in an xterm title bar.

Here's an example of a function, using the second syntax:

     cd()
     {
          builtin cd "$@" &&
          xtitle $HOST: $PWD
     }

This redefines the cd built-in command to allow setting the title of an xterm window to the host name and current directory.

Shell functions can be executed only in the same shell that is used to call that function.  The shell does not fork a copy of itself to interpret the function, like it would with a script.

Local Variables
---------------

Bash supports the use of local variables within a function. A local variable shadows the value of a previously defined variable (local or not) with the same name.

Local variables differ from other variables in only one way: when the function that defined the variable exits, the local variable goes away, and any previously defined variable with the same name becomes visible again.

There is no way to have changes made to a local variable affect the value of any previous variable with the same name.  Local variables have to be exported to be available to programs invoked by that function, and to their children, too.

Local variables are created with the declare or local commands (see Built-in):

declare [-+frxi] [NAME[=VALUE]]
     This command declares variables and gives them attributes.  If no NAME is given, then a listing of the values of variables is displayed, instead.

     The -f option causes declare to use function names only. The -r option causes declare to make NAME readonly. The -x option causes declare to make NAME export only. + and - turn on and off, respectively, the options.

     When declare is used in a function, it makes NAME local, the same as the local command.

          bash$ type z
          z is a function
          z ()
          {
              declare a=2;
              echo in z, a = $a;
          }
          bash$ a=3
          bash$ z
          in z, a = 2
          bash$ echo $a
          3

     The instance of the variable a in the function z is private to z; the value of a in the shell (set by a=3) does not affect it and is not affected by it (as shown by the final echo $a).

local NAME[=VALUE]
     This creates a local variable called NAME, and gives it a value of VALUE.  The local command can be used only within a function; it causes the variable NAME to be restricted to that function and its children.

          bash$ type z
          z is a function
          z ()
          {
              local pid=$$;
              echo This function is executed in shell $pid;
          }
          bash$ echo $pid

          bash$ z
          This function is executed in shell 252
          bash$ echo $pid

          bash$

     The variable pid is private to function z; the calling shell has no such variable.

Here is the declaration of a function that uses a local version of the PATH variable, and executes all of its arguments using a PATH which contains only /bin:

     using_bin () {
       local PATH=/bin
       eval $*
     }

A useful call to this function might look like:

     using_bin "rm *.texinfo; cp ../*.texinfo ."

Returning From Functions
------------------------

A function exits if an error occurs, if a return statement is executed, or after executing the last command.

Here is the syntax of the return command:

     return [N]

This causes a function to exit with the return value specified by N, if present.  If N is omitted, the return status is that of the last command.

Here's an example:

     true()
     {
         return 0
     }
     false()
     {
         return 1
     }

These are replacements for the commands of the same name, and will execute much faster.

Calling Functions
=================

To use a function you must call it.  This works the same way as calling (and using) any program.  Here is the syntax used to call a function:

     FNAME [ ARGS ]

This calls the function named FNAME, and provides it with optional command-line arguments, ARGS.  Here's an example:

     bash$ f /usr/spool/mail/close

This calls the function f with the name of a system mailbox as its argument.  In the body of the function, $1 is replaced with /usr/spool/mail/close.

If you have a function with the same name as an operating system command, you can do one of two things to be able to run that operating system command instead of your function.  You can call the command using its full pathname, or you can use the command command (see Built-in):

     command [COMMAND [ARGS]]

This causes the shell to run the command named in COMMAND with the arguments specified by ARGS, ignoring shell functions.  For example, if you have a shell function called ls, and you want to run the operating system's ls command instead, you'd have to say command ls.

Listing Available Functions
===========================

You can get a list of all the currently defined functions using the -f option of the declare command (see Built-in).  The text of the functions, as well as the function names, is included in the listing.  For example:

     bash$ declare -f
     declare -f f ()
     {
         grep "^From:" ${1-$MAIL};
     }
     declare -f popd ()
     {
         builtin popd "$@";
         xtitle $HOST: $PWD;
     }
     declare -f pushd ()
     {
         builtin pushd "$@";
         xtitle $HOST: $PWD;
     }
     declare -f cd ()
     {
         builtin cd "$@";
         xtitle $HOST: $PWD;
     }
     declare -f xtitle ()
     {
         echo -n -e "\033]2;$*\007";
         echo -n -e "\033]1;$*\007";
     }

This lists the names of the functions together with their definitions.

The Shell Environment
*********************

When a program is invoked it is given an array of strings called the environment.  The shell environment is the set of all shared and exported shell variables and functions.  By typing declare -x, or the export command by itself, you can see a list of all exported variables.  This is a list of name-value pairs, of the form NAME=VALUE:

     bash$ export
     declare -x HOME=/usr/chet
     declare -x SHELL=/bin/bash
     declare -x TERM=xterm
     declare -x USER=chet
     declare -x PATH=/usr/local/bin/gnu:/usr/local/bin:/usr/ucb:/bin:/usr/bin
     declare -x HOSTTYPE=IBMRT
     declare -x MAILCHECK=60
     declare -x BASH=/bin/bash
     declare -x HISTFILE=/usr/chet/.history
     declare -x HISTSIZE=500
     declare -x LOGNAME=chet
     declare -x TZ=EST5EDT
     declare -x MAIL=/usr/chet/mbox
     declare -x HOST=arrakis
     declare -x EDITOR=/usr/local/bin/ce
     declare -x VISUAL=/usr/local/bin/ce
     declare -x PAGER=/usr/local/bin/more
     declare -x DISPLAY=unix:0.0

A process can access and use any environment variables and functions that exist in that process's environment. C programs have a getenv() function available for this purpose.

The shell allows you to manipulate the environment in several ways.  On invocation, the shell scans its own environment and creates a parameter for each name found, automatically marking it for export to child processes.

Generally, this ``basic'' environment consists of (at least) the HOME, PATH and TERM variables.  These tell the shell what your home directory is, the search paths you use most often, and what terminal you want to emulate, respectively.  Other variables are used to customize your environment to make it more useful to you.

Executed commands inherit this environment. If the value of a parameter in the environment is modified, the new value becomes part of the environment, replacing the old.

Therefore, the environment inherited by any executed command consists of the shell's initial environment, whose values may be modified in the shell, less any values removed by the unset command, plus any additions via the export and declare commands.

Remember that exported variables can only be exported to child processes.  If you want to make a variable accessible to all subshells, be sure to define and export it in your login shell.

The environment for any simple command or function can be augmented temporarily by prefixing the command with parameter assignments. These assignment statements affect only the environment seen by that command.

     bash$ foo=bar printenv foo
     bar
     bash$ printenv foo
     bash$

If set -k is used (see Built-in), then all parameter assignments are placed in the environment for a command, not just those that precede the command name.

Shared Variables
================

Normally shell variables are local variables.  That is, these variables are known only to the shell that created them.  When you start a new shell (see Install), the new shell doesn't know about any of the old shell's variables.  Each shell's variables are known only (are local) to itself.

Sometimes, however, we want a new shell to recognize the old shell's variables.  You can accomplish this using the export command (see Built-in):

export NAMES
     exports the value of named variables NAMES to a subshell. Exported variables can only be exported to child processes and not back to parent processes.

export -n NAMES
     removes the export property from the named variables, NAMES.

export
     lists the variables that are already exported.

The export command actually gives only a copy of the original variable to the new subshell.  When the subshell dies, so does the value of the variable copy; the original variable value remains untouched.

Exporting Functions
===================

Normally, functions are unset when the shell executes a shell script. You can get around this problem by exporting your functions to the environment (see Environment).  Exported functions are available to any invocation of the shell, including any shell scripts.  There are two ways you can export functions:  use the -f option of the export command or use the -xf option of the declare command (see Built-in).  Here's how they work:

export -f FNAME
     exports the function named FNAME to the environment.  More than one function name can be listed for export.

export -f
     lists the currently exported functions.

     For example:

          bash$ type fn
          fn is a function
          fn ()
          {
              grep "^From:" ${1-$MAIL};
          }
          bash$ export -f fn
          bash$ export -f
          declare -xf fn ()
          {
              grep "^From:" ${1-$MAIL};
          }

declare -xf FNAME
     exports the function named FNAME to the environment.  More than one function name can be listed for export.

declare -xf
     lists the currently exported functions.

     For example:

          bash$ type fn
          fn is a function
          fn ()
          {
              grep "^From:" ${1-$MAIL};
          }
          bash$ declare -x fn
          bash$ declare -xf
          declare -xf fn ()
          {
              grep "^From:" ${1-$MAIL};
          }

     The first declare statement marks the function fn for export to the environment. The second statement lists all exported functions; in this case fn is the only one.

Command Substitution and Arithmetic Evaluation
**********************************************

Command Substitution
====================

A command enclosed in backquotes, `COMMAND`, is replaced by the output it produces.  This is called command substitution.

For example:

     bash$ echo I am logged in as `whoami`
     I am logged in as jems
     bash$

Inside single quotes, a backslash retains its literal meaning, except when followed by a $, `, or a \.

You can also perform command substitution using the $(COMMAND) syntax. This is the preferred syntax for command substitution. When this form of command substitution is used, none of the characters between the parentheses are treated specially; all characters are considered to make up the command. Here's an example:

     kill -1 $(cat /etc/named.pid)

This sends a hangup signal (SIGHUP) to the process whose process ID is in the file /etc/named.pid.

Note that the command substitution operation replaces any linefeed characters in the command's output with space characters. The shell also deletes trailing newlines. Note, also, that word splitting and path name expansion are not performed on the resulting command if the substitution appears within double quotes.

Command substitutions may be nested.  (When nesting using the `COMMAND` form, protect the inner backquotes with backslashes to prevent shell misinterpretation.)

Command substitution is useful in assigning variables.  Use it when you want the output of a command to be the value of a variable.  For example:

     x=$(pwd)

This assigns x the value of your current working directory.  This example isn't really useful because shell has built-in command (cd) for performing this action. Here's a more useful example:

     i=$(expr $i + 1)

This increments a number if I is a number.  This is useful in shell scripts for creating loops.

Here's another example:

     name=$(basename $i)

This removes all the path information from $I and gives you a pure file name.

A common use of command substitution's linefeed-to-spaces translation is keeping lists of items on separate lines of a file, and then using cat inside of back-quotes to produce word lists for the for command (see for). In the following example, the cat command is used to write the contents of file namelist to the output:

     bash$ cat namelist
     joe
     sam
     mary
     ezekiel
     bash$ echo `cat namelist`
     joe sam mary ezekiel

Here's an example using the file namelist from above:

     bash$ for i in `cat namelist`
     bash> do
     bash> echo "Hi there, $i."
     bash> done
     Hi there, joe.
     Hi there, sam.
     Hi there, mary.
     Hi there, ezekiel.

Arithmetic Evaluation
=====================

You can evaluate arithmetic expressions in BASH.  The syntax for arithmetic evaluation is $[EXPRESSION].  The EXPRESSION is treated as if it were within double quotes, but a double quote inside the brackets is not treated specially.  All tokens in the EXPRESSION undergo parameter expansion, command substitution, and quote removal.  Arithmetic evaluations may be nested.

The evaluation of expressions is done in long integers with no check for overflow, though division by 0 is trapped and flagged as an error.  The following list of operators is grouped into levels of equal precedence operators.  The levels are listed in order of decreasing precedence.

-
     unary minus

!
     logical NOT

* / %
     multiplication, division, remainder (modulus)

+ -
     addition, substraction

<= >= < >
     comparison operators

== !=
     equality, inequality

=
     assignment

Shell variables are allowed as operands; parameter expansion is performed before the expression is evaluated.  The value of a parameter is coerced to a long integer within an expression.  Operators are evaluated in order of precedence.  Subexpressions in parentheses are evaluated first and may override the precedence rules above.  Operators of equal precedence are evaluated from left to right.

You may also specify arithmetic evaluation with the let builtin command.  See Builtin Commands, for more information.

Shell Scripts
*************

A shell script is a collection of operating system commands, comments, and shell programming-language constructs grouped together in a file.

Shell scripts can be composed of fixed commands requiring no arguments, and run without interruption.  Scripts can also be composed of commands that require user input.  If this is the case, the script can obtain that input either by prompting or by arguments included on the command line used to invoke the script.  Scripts can also use pipes and redirection both internally and externally.

You can run shell scripts in a number of ways.  You can type the bash command followed by the script file name, or you can turn the script into an actual command using the chmod command (see chmod (The GNU Utilities Manual)), and execute that new command by typing the script's file name.  Both of the ways of executing a script create a new shell process.

To execute a program without creating a new process you can use the . command or the source command (see Built-in).  These execute a shell script as part of the current process.  Each line in the script is acted upon as if you had typed it, excepting that the shell's notion of interactiveness is turned off.

The exec command (see exec (The GNU Utilities Manual)), also executes programs in place of the current process, but exec never returns control to the original program.

To summarize, here's one of the easiest ways of writing and executing a shell script:

 1. Create a file that contains the commands you want to execute.  For example, a series of commands that you execute frequently and are tired of repeatedly typing.

 2. Change the file access mode so the file can be run like a program rather than be treated like a data file.  For example, chmod +rx FILE, where FILE represents the name of your script.  The +rx option allows all users to read and execute this file.

 3. Type the name of the file to execute the commands in the shell script.

Here's an example of a simple shell script:

     #Display the date, time, username and current directory.
     echo "The current date and time is:"
     date
     echo " "
     echo "You are `whoami` \n"     #print username.
     echo "Your current directory is `pwd`."  #print current directory.

This script prints the current date, time, username and working directory for the user who invokes it.  The first line of this script is a comment, identified by the pound sign # that begins it. Comment statements don't get executed; use them to document your shell script. Notice that comments don't have to be placed on a line by themselves. When a word begins with a # sign, it causes the rest of that line to be interpreted as a comment, and not executed. Note: # works only in a noninteractive shell.

The backquotes around the whoami and pwd commands shows the use of command substitution (see Command Subs).  Basically the shell replaces the command (including the backquotes) with the output of that command.  The \n tells echo to add an extra carriage return to the end of the line.

See Advanced Scripts, for more advanced examples of writing scripts.

Conditionals and Loops
**********************

BASH has some built-in decision-making and looping statements.  Most of these statements base their decisions on the exit, or return, status of specified processes.  An exit status is simply a flag that indicates the success or failure of an executed command. Exit status flags are returned to the parent process when a child process stops executing (for any reason).

For example, suppose we wish to look at the contents of a file using the cat command.  If the specified file cannot be found, it certainly can't be looked at and the attempt to execute cat is looked upon as unsuccessful by the shell.  Therefore the exit status is returned as ``unsuccessful''.

This status can be tested by the shell and used to make decisions about what actions to take next.  An exit status of zero means that the command was executed successfully.  An exit status of non-zero means that the command was unsuccessful.

The if Statement
================

The syntax of the if statement is:

     if CONDITION
     then
         COMMANDS
     [elif CONDITION
     then
         COMMANDS]
     ...
     [else
         COMMANDS]
     fi

where the brackets and the dots indicate that the else part is optional and that there can be any number (including none) of elif parts.

If the commands contained in the first CONDITION are successfully executed, then the commands contained in the first COMMANDS are executed. The optional elif parts allow you to specify conditions to test (and corresponding commands to execute if successful) if previous conditions were not successful. The optional else part allows you to specify commands to execute if none of the CONDITIONs are successful. After the appropriate CONDITIONs are tested and any appropriate COMMANDS are executed, control goes to the statement following the fi.

Here's an example:

     # check to see that we've got sufficient files to bring the
     # system up multi-user
     for i in /bin/login /etc/getty /etc/passwd ; do
         if [ ! -s ${i} ]; then
          echo "${i}: not present ... Can't come up to multi-user mode."
     >/dev/console
          /bin/kill 1
         fi
     done

This is code to execute at the end of the system startup script.  It checks that the necessary files are present to bring the system up to a multiuser state, and shuts the system down if the files are not present.

Here's another example:

     if [ -f /etc/license ] ; then
         PATH=~/bin.vax-ultrix:$PATH
     elif [ -f /hp-ux ] ; then
         PATH=~/bin.hp-ux:$PATH
     elif [ -x /bin/arch ] ; then
         if [ $(/bin/arch) = "sun3" ] ; then
             PATH=~/bin.sun3:$PATH
         else
             PATH=~/bin.sparc:$PATH
         fi
     else
         PATH=~/bin.ibm032:$PATH
     fi

This code tacks a machine-specific binary directory onto the front of the PATH variable.  Only one of the then bodies is executed, depending upon the machine being used.

If you don't want to put the parts of an if statement on separate lines as shown in the syntax, you don't have to. But if you move one of the keywords (then, elif, else, or fi) onto the same line as the preceding CONDITION or COMMANDS, you must put a semicolon before it. In other words, each CONDITION or COMMANDS must be followed by a newline or a ;.

For example:

     if [ "X$PS1" = "X" ]; then exit ; else echo "interactive shell" ;
     fi

This echoes ``interactive shell'' if BASH is executing interactively. The variable PS1 is set only if the shell is interactive.

The case Statement
==================

The syntax of the case statement is:

     case STRING in
          PATTERN_1A | PATTERN_1B | PATTERN_1C)
                 COMMANDS1
                 ;;
          PATTERN_2)
                 COMMANDS2
                 ;;
          ...
     esac

This statement tries to match a string, STRING, to various PATTERNS.  If it finds a match, it executes the corresponding pattern's commands.  When execution is complete, control is transferred to the statement following the esac.

Each pattern in a list is separated from the next by |.  Patterns can contain the file-matching wildcards *, ?, or [ ... ] (see File Names).  A pattern list is ended with a closing parenthesis (note that there is no matching open parenthesis).

You don't have to separate all the parts of the case statement on separate lines as shown above. Any of the newlines can be omitted.

     case STRING in PATTERN1A [| PATTERN1B ...]) COMMANDS [;; ...];; esac

Here's an example:

     cd()
     {
          builtin cd "$@" &&
          case "$1" in
          '')
               PS1='$ '
               ;;
          ..|*/..)
               PS1="${PWD##*/}$ "
               ;;
          */*)
               PS1=${$1##*/}$ "
               ;;
          *)
               PS1="$1$ "
               ;;
          esac
     }

This sets your prompt to contain the name of the current directory, with all path information stripped. This can be used as a way to reset your primary prompt when you change directories.  If you are in your home directory, via a cd with no arguments, PS1 will contain no directory information at all.

The for Statement
=================

The for statement executes a sequence of commands once for each value in a list of items.

The format of the for statement is:

     for NAME [in LIST]
     do
         COMMANDS
     done

For each element in LIST, NAME is set to that element and the COMMANDS are executed. When you omit the optional in LIST, it defaults to in "$@", so that the loop is executed once for each of the command line parameters.

Here's an example:

     for host
     do
          echo $host:
          rsh $host w
     done

This defines a script that runs the w command remotely on each host named as an argument.

Here's an example using the in LIST option:

     for file in $(echo *.c)
     do
          touch $file
     done

This updates the timestamp of each file ending in .c in the current directory.  This is useful for preparing for a rebuild of a software system.

The do and done mark the beginning and the end, respectively, of the loop.  When the LIST is used up, control is passed to the statement following the done.

If you don't want to put the parts of a for statement on separate lines as shown in the syntax, you don't have to. But if you move one of the keywords (do or done) onto the same line as the preceding NAME, LIST, or COMMANDS, you must put a semicolon before it.

while and until Loops
=====================

The format of a while or until loop is:

     while CONDITION
     [do
           COMMANDS]
     done

or

     until CONDITION
     [do
           COMMANDS]
     done

In a while loop, the COMMANDS are repeatedly executed as long as the CONDITION executes successfully (returns an exit status of zero). Before each pass through the loop, CONDITION is executed.  If CONDITION returns zero, COMMANDS is executed.  Usually COMMANDS affects the CONDITION execution in some way so that it will eventually return non-zero.  Otherwise you end up with an infinite loop. When the CONDITION is unsuccessful in executing, control jumps to the statement following the done.

In an until loop, the COMMANDS are repeatedly executed as long as the CONDITION fails execution (returns an exit status of non-zero). Before each pass through the loop, CONDITION is executed. If CONDITION returns non-zero, COMMANDS is executed. Usually COMMANDS affects the CONDITION execution in some way so that it will eventually return zero.  Otherwise you end up with an infinite loop. When the CONDITION is successful in executing, control is returned to the statement following the done.

The following example tests the output of the who command once each minute until it finds that a user named chet has logged in.

     until who | grep chet
     do
          sleep 60
     done

If you don't want to put the parts of a while or until statement on separate lines as shown in the syntax, you don't have to. But if you move one of the keywords (do or done) onto the same line as the preceding CONDITION or COMMANDS, you must put a semicolon before it. In other words, the CONDITION and COMMANDS must each be followed by a newline or a ;.

The do COMMANDS is optional.  Sometimes just testing the CONDITION is enough.  For example, here's an inefficient way of reading the last line of a file:

     exec < file
     while read variable ; done

The return status of read is 0 (successful) unless the end-of-file (EOF) is encountered.  When the EOF is encountered, the condition is met and the usefulness of the statement is finished.  No do COMMANDS section is needed.

The break and continue Statements
=================================

You can interrupt a for, while, or until loop using a break or a continue statement:

break [N]

     The break statement stops the execution of the loop and passes control to the statement following the done that marks the end of the loop. If N is specified, it tells the shell to break at the Nth level of the enclosing loop.

     Here's an example:

          while :
          do
               echo -n "Enter name of file to print [q to quit]: "
               read fn
               if [ "$fn" = "q" ] ; then
                    break
               fi
               lpr $fn
          done

     This prompts for names of files and prints them, until a q is encountered.

continue [N]

     The continue statement transfers control to the loop's done statement, which continues execution of the loop.  If N is specified, it tells the shell to resume computation at the Nth enclosing loop.

     Here's an example:

          for dir in $(cat dirlist)
          do
               if [ -d $dir ] ; then
                    continue
               fi
               mkdir $dir
          done

     This reads a file containing the names of a list of directories to create, and creates each one if it does not already exist.

Built-in Shell Commands
***********************

Some of the commands you may want to run are already part of the shell. Because of this, no new processes are started in order to run these built-in commands.  Therefore, these built-in commands use less time than those that aren't built-in.

The following is a list of the built-in commands.  Some of these commands are explained in more detail earlier in this manual. You are directed to read the appropriate chapter if you need more information than is provided here:

:
     This command can only expand arguments and perform redirections and nothing else.  It is the shell's ``do nothing'' command.  It is not, however, a useless command.  Since the shell is able to scan and parse the line that follows the colon, this command can be adapted for many uses.

     It can be used as a valid option for a program's conditional statement, or it can be used to create an infinite (until interrupted) loop. Here's an example:

          # wait for a file to be created, chewing up lots of CPU time
          # usage: waitfor filename
          #
          while [ ! -f "$1" ] ; do
                :
          done

     You can also use the colon to create comment lines, instead of using the # character (see Scripts, for more information). For example:

          bash$ echo A bad example > junk
          bash$ cat junk
          A bad example
          bash$ : this is a comment about > junk
          bash$ cat junk
          bash$

     First we create the file called junk, entering a simple message into that file.  Then we create a comment about our file using the : statement and insert a redirection operator into the sentence. Normally we'd expect the shell to ignore anything that follows a comment character.  However, the shell is able to parse and interpret the contents of the line following a colon. Therefore, the above : statement, when scanned by the shell, causes the file junk to be opened for output, which removes its prior contents (see Redirection).

     So be careful when using the : statement.  It can be useful when used properly; but it can also be dangerous in careless hands. Don't insert any characters that can be expanded by the shell into a : comment line. It's safest to protect the comment following : with single quotes so that it won't be interpreted by the shell. Make sure that there's a space between the colon and the opening single quote, though, or the shell could mistake what follows for a command:

          bash$ : 'This is a good way to make a comment.'
          bash$ :'This is bad.'
          :This is bad.:  command not found.

. FILE
source FILE
     Both commands are used to execute shell programs, without creating a separate child process.  The named file is read and executed in the current shell environment and control is returned to the current shell. Since these commands do not create a subshell they can be used to change the value of a shell variable in the current shell.

     FILE must have a fully qualified path name in order to be executed.  The PATH variable is searched for the location of the named file, otherwise the current directory is searched if no file is found in PATH.

     Redirection of input and output and other command line arguments are not permitted when using these commands.

alias [NAME[=VALUE] ...]
     An alias is defined for each NAME whose VALUE is given. See Aliases, for more information.  A trailing space in VALUE causes the next word to be checked for alias substitution.  If a NAME (without the =VALUE part) is given for which no alias has been defined an error message is printed.

     The alias command, with no arguments, prints the list of aliases in the form NAME=VALUE on the standard output.

bg [JOB_SPEC]
     This causes the shell to place the specified job, JOB_SPEC, in the background, as if it had been started with &.  See Resuming, for more information.  If JOB_SPEC is not present, the shell's notion of the current job is used.

break [N]
     This command exits from an existing for, while, or until loop.  If N is specified, it tells the shell to break at the Nth level of the enclosing loop.  N must be greater than or equal to 1.  If N is greater than the number of the enclosing loops, all enclosing loops are exited.

builtin [SHELL-BUILTIN [ARGUMENTS]]
     This is used to execute a built-in shell command, passing it ARGUMENTS.  This is useful when you wish to rename a built-in shell command to be a function, but need the functionality of the built-in command within the function itself.  (The built-in cd command is commonly redefined this way.)

cd [DIR]
     This command tells the shell to change the current directory to the one specified by DIR.  The variable HOME contains the default value of DIR.

     The variable CDPATH defines the search path for the directory containing DIR.  See Predefined, for more information. Alternative directory names are separated by a colon, :.

     A null directory name is considered to be the same as the current directory.  If DIR begins with a forward slash, /, then the search path contained in CDPATH is not used.

command [COMMAND [ARGUMENTS]]
     This causes the shell to run the [external] command named in COMMAND with the arguments specified by ARGUMENTS, ignoring all other shell functions.

     For example, if you have a shell function called ls, and you want to call the command ls as well, you can say command ls.

continue [N]
     This command tells the shell to resume the next iteration of the enclosing for, while, or until loop at the Nth enclosing loop (if N is specified).  N must be greater than or equal to 1.  If N is greater than the number of enclosing loops, the last enclosing loop (the ``top-level'' loop) is resumed.

declare [-+frxi] [NAME[=VALUE]]
     This command declares variables and gives them attributes.  If no NAME is given, then a listing of the values of variables is displayed instead.

     -f
          Use function names only.

     -r
          Make NAME readonly.  These names cannot be assigned values by subsequent assignment statements.

     -x
          Make NAME export to subsequent commands via the environment.

     -i
          Treat NAME as an integer; arithmetic evaluation (see Arithmetic Evaluation) will be performed when the variable is assigned a value.

     Using + instead of - turns off the attribute.

     When declare is used in a function, it makes NAME local, the same as the local command (see Functions).

dirs
     This displays the list of currently remembered directories. Directories are added to the list with the pushd command; you can get back up through the list with the popd command.

echo [-ne] [arguments]
     This displays a prompt or a message on the standard output.  It outputs the ARGUMENTS, if supplied, separated by spaces.  If the -n option is specified, the trailing newline character is suppressed.

     If the -e option is given, interpretation of the following backslash-escaped characters is turned on:

     \a
          Alert/bell.

     \b
          Backspace.

     \c
          Suppress trailing newline.

     \f
          Form feed.

     \n
          New line.

     \r
          Carriage return.

     \t
          Horizontal tab.

     \v
          Vertical tab.

     \NNN
          The character whose ASCII code is NNN (octal).

     \\
          Backslash.

enable [-n] [NAMES]
     This command enables and disables built-in shell commands.  This allows you to use an operating system command which has the same name as a built-in shell command.

     If the -n option is used, the named commands, NAMES, become disabled.  Otherwise the named commands are enabled.

     For example, to use the test command found in your path instead of the built-in shell version, you type enable -n test.

eval [ARGUMENTS]
     The ARGUMENTS are read and concatenated together into a single command.  This ``new'' command is then read and executed by the shell.

exec [[-]COMMAND [ARGUMENTS] ]
     If COMMAND is specified, it is executed, replacing this shell, without creating a new process.  The ARGUMENTS become arguments to COMMAND.

     If the first argument is -, the shell places a dash in the zeroth argument passed to COMMAND (exactly what a login does).

     If the COMMAND can't be executed the shell exits, unless the shell variable no_exit_on_failed_exec exists.

     If COMMAND is not specified, any redirections present take effect in the current shell.

exit [N]
bye [N]
     This causes the shell to exit with the status specified by N.  If N is omitted, the exit status is that of the last command executed.  A trap on the shell variable EXIT is executed before the shell terminates.

export [-nf] [NAME[=WORD]]
     The export command exports the value of named variables (or functions if the -f option is specified), NAME, to a subshell.

     If no variable names are given, export displays a list of all the variables that are already exported.  The -n option causes the shell to remove the export property from the named variables.

fg [JOB_SPEC]
     This places the specified job, JOB_SPEC, in the foreground, and makes it the current job.  See Resuming, for more information.  If JOB_SPEC is not present, the shell's notion of the current job is used.

function NAME () [ COMMANDS ; ]
NAME () [ COMMANDS ; ]
     This creates a simple command invoked by NAME which executes the named COMMANDS (see Functions).  Arguments on the command line along with NAME are passed to the function as $0 ... $N (see Positional).

hash [-r] [NAME]
     For each variable name, NAME, the full pathname of the command is determined and remembered.  The -r option causes the shell to forget all remembered locations.  With no arguments, hash presents information about remembered commands.

help [PATTERN]
     This command displays helpful information about built-in commands.  If a pattern is specified, help gives detailed help on all commands matching PATTERN, otherwise a list of the built-ins is printed. If PATTERN contains only alphanumeric characters (no wildcard characters, such as ? and *), then a pattern of pattern* if assumed.  Therefore, the command help pw will produce help on the pwd command.

history [N]
history -rw [FILE]
history -s ARGUMENTS
     The first command displays the history list with line numbers.  Lines listed with a * have been modified.  If a number N is specified, only the last N lines of the history list are displayed.

     The -w option means causes the current history file to be written out.  The -r option causes the current history file to be read, instead.  If a file name, FILE, is given, then that file is used as a history list.  If no file name is given, BASH checks to see if the variable HISTFILE is set.  The file ~/.bash_history is used as the history file if the variable HISTFILE is not set. See History, for more information.

     The -s option performs history substitution on the named arguments.

jobs [-l]
     This lists the active jobs.  The -l option causes the list of process identification numbers to be listed in addition to the normal information.  See Job Control, for more information.

kill [-SIGSPEC] PID
kill [-SIGSPEC] JOB_SPEC
kill -l
     This sends the processes named by PID or JOB_SPEC the terminate signal, or the signal specified by SIGSPEC, if present.  Signals are specified either by number or by name.

     The -l option lists the signal names that can be sent.  Typing kill alone does nothing.  See kill, for more information.

let EXPRESSION [EXPRESSION ...]
     Each EXPRESSION is an arithmetic expression to be evaluated (see Arithmetic Evaluation).  If the last EXPRESSION evaluates to 0, let returns 1; otherwise 0 is returned.

local NAME[=VALUE]
     This creates a local variable called NAME, and gives it a value of VALUE.

     When the local command is used within a function it causes the variable NAME to be restricted to that function and its children. Otherwise it is equivalent to creating normal variables, as if the local command had been omitted.

     When used without options, local gives a list of local variables on the standard output.

logout
     This exits a login shell.

popd [+-N]
     This removes entries from the directory stack.  With no arguments, it removes the top directory from the stack, and changes directories (cd) to the new top directory.

     The +N option removes the Nth entry (counting from the left of the list shown by the dirs command), starting with zero.  For example:  popd +0 removes the first directory, while popd +1 removes the second.

     The -N option removes the Nth entry (counting from the right of the list shown by the dirs command), starting with zero.  For example:  popd -0 removes the last directory, while popd -1 removes the next to last.

     You can see the directory stack with the dirs command.

     If the variable PUSHD_SILENT is not set, and the popd command	was successful, a dirs will be performed too.

pushd [DIR]
pushd [+-N]
     This adds a directory to the top of the directory stack, or rotates the stack, making the new top of the stack the current working directory. With no arguments, it exchanges the top two directories.

     The +N option rotates the stack so that the Nth directory (counting from the left of the list shown by the dirs command) is at the top.

     The -N option rotates the stack so that the Nth directory (counting from the right of the list shown by the dirs command) is at the top.

     The DIR option adds the directory named by DIR to the directory stack at the top, making it the new current working directory.

     You can see the directory stack using the dirs command.

     If the variable PUSHD_SILENT is not set, and the pushd command was successful, a dirs will be performed too.

read [NAMES]
     This reads values from the standard input into various shell variables.  One line is read from the standard input, and the first word is assigned to the first named variable in NAMES, the second word to the second named variable, and so on, with leftover words assigned to the last named variable.

     Only the characters in IFS are recognized as word delimiters (see Predefined).

readonly [-f][NAMES]
     The given NAMES are marked readonly and the values of these various NAMES may not be changed by subsequent assignments. If the -f option is given, the functions corresponding to the NAMES are marked instead.  If no arguments are given, a list of all read-only names is printed.

return [N]
     This causes a function to exit with the return value specified by N.  If N is omitted, the return status is that of the last command executed in the function body.

set [-aefhkntuvxldo] [ARGUMENTS]
     The set command sets options for the shell:

     a
          This marks variables which are modified or created for export.

     e
          This tells a non-interactive shell to exit immediately if a command exits with a non-zero status.

     f
          This disables path name expansion.

     h
          This tells the shell to locate and remember function commands as those functions are defined.  Normally, function commands are looked up when the function is executed.

     k
          This tells the shell to place all keyword arguments in the command's environment.  Normally only those that precede the command name are placed in the environment for a command.

     n
          This tells the shell to read commands but not execute them.  This may be used to check a shell script for syntax errors, for example. This option is ignored in interactive shells.

     t
          This tells the shell to exit after reading and executing one command.

     u
          This tells the shell to treat unset variables as an error when performing substitutions.  If a substitution is attempted on an unset variable, the shell prints an error message.  If the shell is non-interactive, it then exits with a non-zero status.

     v
          This prints shell input lines as they are read.

     x
          This prints the value of PS4 followed by commands and their arguments as they are executed.

     l
          This saves and restores the bindings of the NAME in a for command (see for).

     d
          This disables the hashing of commands that are looked up for execution. Normally, commands are remembered in a hash table and, once found, do not have to be looked up again.

     H
          This enables the ! style history substitution (see History). This option is on by default.

     o [OPTION-NAME]
          The OPTION-NAME can be one of the following:

          allexport
               Same as -a.

          braceexpand
               The shell will enable curly brace expansion (SEE BRACE EXPANSION).  This is on by default.

          emacs
               Use an emacs-style command line editing interface

          errexit
               Same as -e.

          histexpand
               Same as -H.

          ignoreeof
               The effect is as if the shell command ignoreeof=10 had been executed (see Shell Variables).

          monitor
               Same as -m.

          noclobber
               The effect is as if the shell command noclobber= had been executed (see Shell Variables).

          noexec
               Same as -n.

          noglob
               Same as -f.

          nohash
               Same as -d.

          notify
               The effect is as if the shell command notify= had been executed (see Shell Variables).

          nounset
               Same as -u.

          verbose
               Same as -v.

          vi
               Use a VI-style command line editing interface.

          xtrace
               Same as -x.

          If no OPTION-NAME is supplied, the values of the current options are printed.

     You can turn these options on and off by preceding the option letter with - for on, and + for off.  You can also set these options on the command line that invokes the shell.  For example:

          bash$ bash -v

     The special shell variable, $- lists the currently defined shell options.

     You can also use the set command to assign values to positional parameters (see Parameter Subs):

          set test junk

     sets the positional parameter $1 to test and $2 to junk. The ARGUMENTS are passed as positional parameters $1 to $N.

     If you type the set command alone, with no arguments, you get a list of all the currently defined shell variables (see Variables).

shift [N]
     This causes the positional parameters from $N+1 on up to be renamed to $1, $2, and so on.  If N is not given, it is assumed to be 1.

suspend [-f]
     This suspends the execution of this shell until it receives a ``resume'' (SIGCONT) signal.  The -f option, if specified, prevents messages about this being a login shell (if it is) and causes the shell to be suspended quietly anyway.

test [EXPR]
[EXPR]
     These test for various conditions named in EXPR.  They return a status of of 0 (true) or 1 (false) depending on the evaluation of EXPR.

     Expressions can be unary or binary.  Unary expressions are often used to examine the status of a file.  You can have string operators and numeric comparison operators too.

     File operators:

     -b FILE
          This tests that the file FILE exists and is a block special file.

     -c FILE
          This tests that the file FILE exists and is a character special file.

     -d FILE
          This tests that the file FILE exists and is a directory.

     -f FILE
          This tests that the file FILE exists and is not a directory (tests that it is a plain file).

     -g FILE
          This tests that the file FILE exists and has the set-group-ID bit set.

     -k FILE
          This tests that the file FILE exists and has its ``sticky'' bit set.

     -L FILE
          This tests that the file FILE exists and is a symbolic link.

     -p FILE
          This tests that the file FILE exists and is a named pipe.

     -r FILE
          This tests that the file FILE is readable by you.

     -s FILE
          This tests that the file FILE exists and is not empty (has a non-zero size).

     -S FILE
          This tests that the file FILE exists and is a socket.

     -t [FD]
          This tests to see if file descriptor FD is opened on a terminal. If FD is omitted, it defaults to 1 (the standard output).

     -u FILE
          This tests that the file FILE exists and has the set-user-ID bit set.

     -w FILE
          This tests that the file FILE exists and is writable by you.

     -x FILE
          This test that the file FILE exists and is executable by you.

     -O FILE
          This tests that the file FILE exists and is, effectively, owned by you.

     -G FILE
          This tests that the file FILE exists and is owned by the effective group ID.

     FILE1 -nt FILE2
          This tests that the files FILE1 and FILE2 exist and that FILE1 is newer than FILE2 (according to modification date).

     FILE1 -ot FILE2
          This tests that the files FILE1 and FILE2 exist and that FILE1 is older than FILE2 (according to modification date).

     FILE1 -ef FILE2
          This tests that the files FILE and FILE2 exist and that they have the same device and inode numbers.

     String operators:

     -z STRING
          This tests that STRING exists and is empty (of zero length).

     -l STRING
          When this is used as an operand to any of the binary arithmetic operators it returns the length of STRING.

     -n STRING
     STRING
          This tests that STRING exists and is not empty (has a non-zero size).

     STRING1 = STRING2
          This tests that STRING1 and STRING2 exist and are equal.

     STRING1 != STRING2
          This tests that STRING1 and STRING2 exist are not equal.

     Other operators:

     ! EXPR
          This tests that EXPR exists and is false.

     EXPR1 -a EXPR2
          This tests that EXPR1 and EXPR2 exist and are both true.

     EXPR1 -o EXPR2
          This tests that EXPR1 and EXPR2 exist and that at least one of them is true.

     ARGUMENT1 OP ARGUMENT2
          OP represents one of the arithmetic binary operators -eq (equals), -ne (not equals), -lt (less than), -le (less than or equal to), -gt (greater than), or -ge (greater than or equal to).

          This tests to see if ARGUMENT1 and ARGUMENT2 exist and also tests if ARGUMENT1 is equal, not equal, less than, less than or equal to, greater than, or greater than or equal to ARGUMENT2, depending upon the operator used.

times
     This prints the accumulated user and system times for the shell and for processes started from the shell.

trap [-l] [ARGUMENTS] [SIGSPEC]
     The command named by ARGUMENTS is to be read and executed when the shell receives the signal(s) specified by SIGSPEC. SIGSPEC is either a signal name in <signal.h>, or a signal number.  The trap command with no arguments prints the list of commands associated with each signal number.  The -l option causes the shell to print a list of signal names and their corresponding numbers.

     If ARGUMENTS is absent, all specified signals are reset to their original values.  If ARGUMENTS is the null string, the signal is ignored by the shell and by the commands it invokes.

     If SIGSPEC is EXIT (0), the command ARGUMENTS is executed upon exit from the shell.

type [-all] [-type | -path] [NAMES]
     This allows you to test to see how each named item, NAME, would be interpreted if used as a command name.

     If the -type option is used, it returns a single word, either alias, function, builtin, or file, if NAME is an alias, shell function, shell builtin, or disk file, respectively.  If the name is not found, nothing is printed.

     If the -path option is used, type returns either the name of the disk file that would be executed, or nothing if -type doesn't return a value of file.

     If the -all option is used, it displays all of the interpretations of NAMES.  This includes aliases and functions, if and only if the -path option is not also used.

ulimit [-cdfmst [LIMIT]]
     ulimit provides control over the resources available to processes started by the shell, on systems that allow such control.  If an option is given, it is interpreted as follows:

     -c
          refers to the maximum size of core (memory dump) files created.

     -d
          refers to the maximum size of a process's data segment.

     -f
          refers to the maximum size of files created by the shell.

     -m
          refers to the maximum resident set size.

     -s
          refers to the maximum stack size.

     -t
          refers to the maximum amount of cpu time, in seconds.

     If LIMIT is given, it represents the new value of the specified resource.  Otherwise, the current value of the specified resource is printed.

     If no options are given, the -f is assumed to be active.  Values are in 1k increments, except for -t, which is in seconds.

umask [NNN]
     This sets the user file-creation mask to the octal number NNN. If NNN is omitted, the current value of the mask is printed.

unalias [NAMES]
     This removes the named alias(es), NAMES, from the list of defined aliases.

unset [-f] [NAMES]
     This removes the corresponding variable or function specified by NAMES.  If the -f option is given, then functions are removed.

     The predefined variables PATH, IFS, PPID, PS1, PS2, UID, and EUID cannot be unset (see Shell Vars).

wait [n]
     This asks the shell to wait for the specified process, N, and report its termination status.  N can be a process ID or a job specification.  If a job specification is given, all processes in that job's pipeline are waited for.

     If N is not given, all currently active child processes are waited for, and the return code is zero.  See wait, for more information.

Variables Set or Used by the Shell
**********************************

The following variables are set by the shell. See Variable Mechanics, for information on shell variables.

PPID
     This is the PID (process id) of the shell's parent.

PWD
     This is the current working directory. (It's called PWD because it is the directory name the pwd command would report.) It is updated when you change directories with the cd command.

OLDPWD
     This is the previous working directory. When you change directories with the cd command, the directory you move to goes into PWD and the directory you move from goes into OLDPWD.

REPLY
     This is set by the read built-in command (see Built-in) when no arguments are supplied.

UID
     This expands to the user ID of the current user.

EUID
     This expands to the effective user ID of the current user.

BASH
     This expands to the full pathname used to invoke this instance of BASH.

BASH_VERSION
     This expands to the version number of this instance of BASH.

SHLVL
     This is incremented by one each time an instance of BASH is started.

RANDOM
     Each time this variable is referenced, a random integer is generated. The sequence of random numbers may be initialized by assigning a value to RANDOM.  If RANDOM is unset, it will lose its special properties, even if it is subsequently reset.

SECONDS
     Each time this variable is referenced, the number of seconds since shell invocation is returned.  If a value is assigned to SECONDS, the value returned upon subsequent references is the number of seconds since the assignment plus the value assigned.  If SECONDS is unset, it will lose its special properties, even if it is subsequently reset.

LINENO
     Each time this variable is referenced, the shell substitutes a decimal number representing the current sequential line number (starting with 1) within a script or function.  When not in a script or function, the value substituted is not guaranteed to be meaningful.  When in a function, the value is not the number of the source line that the command appears on (that information has been lost by the time the function is executed), but is an approximation of the number of commands executed in the current function.  If LINENO is unset, it will lose its special properties, even if it is subsequently reset.

The following variables are used by the shell.  In some cases, as noted below, BASH assigns these variables default values:

HOME
     This represents the default argument for the cd command.  (That is, the command cd with no arguments will connect to this directory.)  It is usually your login directory.  For example:

          HOME=/usr/home/close

     HOME is automatically set to your login directory when you log in.

PATH
     This is the search path to use when the shell looks for program files referenced in commands.  Separate directory names using colons.  Here's an example:

          /usr/gnu/bin:/usr/local/bin:.:/usr/ucb:/bin:/usr/bin/X11:/usr/bin

CDPATH
     This is the search path for the cd command.  Separate directory names using colons.  Here's an example:

          CDPATH=.:~:/usr/src

IFS
     This defines the internal field separators.   These are the characters that separate words. It has a default value of space, tab, and newline characters.  Here's an example:

          IFS=':'

     This allows you to read the password file as separate fields.

ENV
     If this parameter is set when BASH is executing a shell script, its value is interpreted as a file name containing commands to initialize the shell (like .bashrc for interactive shells).

MAIL
     This is the file name to use as your mailbox.  If this file is non-zero in length and has been modified since the last time the shell checked the file, the shell displays the message ``you have mail''.  You control how often the shell checks this file by setting the MAILCHECK variable.

     Here's an example using the MAIL variable:

          MAIL=/usr/homes/close/mbox

     This causes the shell to check for mail in /usr/homes/close/mbox rather than the system spool directory.

MAILCHECK
     This specifies the amount of time that must pass before the shell will check the file named by the MAIL variable to see if it has changed.  The default is 60 seconds (1 minute).  An interval of 0 causes the shell to look for mail before printing each prompt.

     For example,

          MAILCHECK=600

     causes the shell to check for mail before printing a prompt if 600 seconds have passed since the last check.

MAILPATH
     This specifies multiple mailboxes for the shell to check.  It is the path the shell uses to check the named files for modifications (receipt of mail).  To distinguish which file has received mail, you can follow each file name with a % and some unique text which is printed when mail is received.  Separate file names with colons.  Here's an example:

          MAILPATH='/usr/homes/close/mbox?"You have mail":~/shell-mail?"$_ has
          mail!"'

     This causes the shell to print ``You have mail'' whenever it detects a change in the modification time of the file /usr/homes/close/mbox.  Additionally, the file /usr/homes/close/shell-mail is also checked, and the message ``/usr/homes/close/shell-mail has mail!'' is printed whenever a change is detected in its modification time.

MAIL_WARNING
     If this variable is set and one of the specified mail boxes has been accessed since the last time BASH checked, then the message ``The mail in <mailfile> has been read!'' is printed.

PS1
     This is the primary prompt string.  By default it is bash\$ . Here's an example:

          PS1="$(whoami)@$(hostname)$ "

     This sets the primary prompt string to be the login name of the current user, followed by the name of the computer, followed by a dollar sign.

PS2
     This is the secondary prompt string.  By default it is bash>. For example,

          PS2='more> '

     sets the secondary prompt string to more> .  This is printed whenever bash needs more input to complete a command.

PS4
     This is the prompt string printed before each command BASH displays during an execution trace.  By default, it is +.

NO_PROMPT_VARS
     If this is set, the decoded prompt string does not undergo further expansion.

HISTSIZE
     This is the number of commands to remember in the command history list (see History).  Its default value is 500.

HISTFILE
     This is the name of the file in which the command history list is saved (see History).

PROMPT_COMMAND
     If this is set, the value is executed as a command prior to issuing each primary prompt.

IGNOREEOF
ignoreeof
     This controls the action of the shell on receipt of an end-of-file character as the sole input.  If set, the value is the number of consecutive end-of-file characters typed before bash will exit.

     If the variable exists but does not have a numeric value, or has no value, the default value is 10.  If it does not exist, an end-of-file signifies the end of input to the shell.  This is only in effect for interactive shells.

HOSTTYPE
     This is automatically set to a string that uniquely describes the type of machine on which BASH is executing.  The default is system-dependent.

TMOUT
     If this is set to a value greater than zero, the value is interpreted as the number of seconds to wait for input after issuing the primary prompt.  BASH will terminate after waiting for the number of seconds.

notify
     If this is set, BASH will report terminated background jobs immediately, rather than waiting until printing the next primary prompt (see notify).

history_control
     If this is set to a value of ignorespace, lines that begin with a space won't be entered in the history list.

     If this is set to a value of ignoredups, lines that match the last line entered in the history list won't be recorded.

     If this is unset, or set to any other value than those above, all lines read by the shell are saved in the history list.

glob_dot_filenames
     If this is set, BASH includes file names beginning with a . in the results of pathname expansion.

allow_null_glob_expansion
     Normally, a filename pattern that doesn't match any files is left in the command as is (expands to itself) .  For example, *.foo is left as is if there are no files ending in .foo. If allow_null_glob_expansion is set, however, a pattern that doesn't match anything is removed from the command (expands to a null file name).

histchars
     This represents the two characters which control history expansion and tokenization.  The first character is the history expansion character; that is, the character which signals the start of a history expansion (normally !).

     The second character is the character which signifies that the remainder of the line is a comment, when found as the first character of a word.

nolinks
     If this is set, the shell doesn't follow symbolic links when doing commands that change the current working directory.  By default, BASH follows the logical chain of directories when performing commands such as cd.

hostname_completion_file
     This contains the name of a file, in the same format as /etc/hosts, that should be read when the shell needs to complete a hostname.  You can change the file name interactively; the next time you want to complete a hostname BASH adds the contents of the new file to the already existing database.

noclobber
     If this is set, BASH will not overwrite an existing file with the >, >&, and <> redirection operators. Such an attempt to overwrite a file will generate an error message. You can override this via the >| redirection operator.  The >> (append) redirection operator will still work on existing files because it only appends to the file and doesn't erase the file's current contents.

auto_resume
     This variable determines whether a command may restart a suspended job rather than starting a new one. See Resuming, for more information.

no_exit_on_failed_exec
     If this variable exists, the shell doesn't exit if it can't execute the file specified in an exec command (see Built-in).

cdable_vars
     If this is set, an argument to the cd built-in command that is not a directory is assumed to be the name of a variable whose value represents the directory to which you would like to cd.

pushd_silent
     If this is set, the pushd and popd built-in commands will not print the current directory stack after successful execution.

Installing BASH
***************

This appendix tells how to install BASH on a machine. If BASH is already on your machine, or you are not the person installing it, ignore this appendix.

To install BASH you simply type make. The BASH Makefile tries to dynamically figure out what kind of machine and operating system you are using.  It makes an educated guess based on the information it finds.

During the make process, a message is displayed describing what machine and operating system has been chosen for you.  This information is also saved in the file .machine so you can look at it later.

Therefore, for most machines, simply follow this simple checklist to install BASH:

 1. Type make.

 2. Wait for the compilation to finish.

 3. Type ./bash to see if the compile worked.

 4. Type cp ./bash /usr/gnu/bin/bash (or wherever you keep GNU binaries) to copy BASH to your binaries directory.

What if it Doesn't Install so Easily?
=====================================

Sometimes BASH gets confused and will make the wrong assumptions about your machine or operating system.  If the displayed information (also found in .machine) is incorrect, you will have to edit the file machines.h and provide the appropriate information so that BASH can be installed correctly.  The complete instructions for doing this are located in the machines.h file.

However, if BASH says that your machine type is an UNKNOWN_MACHINE, or BASH thought it knew something about your machine but was wrong, then reading the next few sections could be of use to you see Files, and Porting, for more information).

Files Used in the make Process.
===============================

The following files are used during the installation of BASH, in the make process:

Makefile
     This is responsible for making the actual Makefile that is used to create Bash.  It runs the C preprocessor (usually located in /lib/cpp) on the file cpp-Makefile, producing the output file bash-Makefile.

cpp-Makefile
     This is a file of C comments and text.  It contains ifdefs that control what files get compiled and which flags are passed to the various C files comprising BASH.  It includes a file called machines.h.

machines.h
     This file contains the basic compilation parameters for all of the machines to which BASH has been ported.  This file consists of a series of conditional blocks, one per machine type.

     These conditional blocks are depend upon the unique identifier that cpp has predefined for this machine.  In some cases, additional information can be passed from Makefile.  It is possible to pass information such as whether or not a particular file is available on this system, and so on.

bash-Makefile
     This is the output from the initial stage of make.  It is a stripped down version of cpp-Makefile which is tailor-made for your machine and operating system.  All subsequent makes use this file.

What if You Have to Port to a New Machine?
==========================================

To port BASH to a previously unsupported machine, you need to create a block in machines.h that is conditional based on a unique identifier present in your version of the C preprocessor.

If you don't know what that symbol is, you might try the following simple test:

     bash$ echo "main () { }" > foo.c
     bash$ cc -v foo.c

The first command puts a small C program into the file foo.c, and the second program compiles that program. The -v option ???.

Look for something of the form -DMACHINE in the output of cc, where MACHINE is an identifier for your machine.  If your machine's C preprocessor doesn't have a unique identifier, you will have to define the identifier in Makefile manually.

Let's say you have a machine from Yoyodyne Industries, called the YoYo. It runs a version of BSD, so it is reasonably compatible. However, the cpp file on this YoYo machine doesn't define any unique identifiers. You should change the Makefile line for CPPFLAGS to:

     CPPFLAGS = -P -DYoYo

Then, in machines.h, make a copy of the block for UNKNOWN_MACHINE, and change the conditional to:

     #if defined (YoYo)

Inside the YoYo block, define M_MACHINE="YoYo" and M_OS=BSD.  You also modify the existing defines to match your machine's software.

If BASH still won't compile, perhaps because of missing code that is required for your YoYo machine, you will have to write that code and place it within a conditional block based on YoYo.

Most machines aren't that difficult; simply redefining a few of the default values is sufficient.  If you do run across a difficult machine, please send all fixes and changes to bash-maintainers@ai.mit.edu in the form of context diffs:

     diff -c orig-machines.h machines.h >machines.diffs

Please include information about which version of the shell you have.

Reporting Bugs
==============

If you find a bug in BASH, you should report it.  But first you should make sure that it really is a bug and that it appears in the latest version of BASH that is available.

Once you have ascertained that a bug really exists, you are welcome to mail in a bug report.  If you have a fix, please mail that too!

Suggestions and ``philosophical'' bug reports should be mailed to bug-bash@ai.mit.edu.  Genuine bug reports should be mailed to the same place, or to bash-maintainers@ai.mit.edu.

All bug reports should include:

  * The version number of BASH.

  * The hardware and operating system used.

  * The compiler used to compile BASH.

  * A description of the bug's behavior.

  * A short script or ``recipe'' which demonstrates the bug.

Without this information, it is generally not possible to successfully debug BASH.  Usually, without this information, the bug won't manifest itself!

Discussion and questions about BASH in general (including questions about this documentation) can be sent to bug-maintainers@ai.mit.edu.

Invoking BASH
*************

The operating system starts a shell for you when you log in.

This shell operates interactively; that is, it prompts you for commands and processes those commands.  Logging off the system ends this login shell.

A login shell is one that's been started with the -login flag, or one whose first character of argument 0 is a -. An interactive shell is one that has been started with the -i flag, or one whose standard input and standard output are both connected to terminals.

A shell doesn't always have to be interactive.  For example, if you use a sequence of commands frequently, you can save time typing by storing those commands in a file and direct the shell to execute this command file when you need it.  When this command file is executed a new non-interactive shell is started to read and execute the commands in that file.

You can tell if a shell is interactive or not by examining the contents of the variable PS1.  It is unset in non-interactive shells, and set in interactive ones.

Automatic Script Execution
==========================

Upon starting a login shell, the system looks for a file containing system-wide start-up instructions for BASH and reads and executes it. Usually these instructions are in a file called /etc/profile.

Next the system looks for start-up instructions for your account and reads and executes it.   These instructions are found in one of the following files; the system searches for the following files, in order, and reads and executes the first one it finds:

~/.bash_profile

~/.bash_login

~/.profile

Since the chosen file contains start-up instructions for your account, you can modify and ``personalize'' this file if you want. See Start-up, for an example of this type of file (~/.bash_profile).  If BASH can't find any of these files, BASH starts with a default environment; no error message is given.

When exiting a login shell, BASH reads and executes the file ~/.bash_logout, if it exists. See Start-up, for an example of this type of file.

Upon starting a non-login, interactive shell, BASH reads and executes the file ~/.bashrc if it exists. See Start-up, for an example of this type of file.

Upon starting a non-interactive shell, BASH checks to see if the environment variable ENV is non-null, and reads and executes the file named by that variable.

Options That Modify the Shell Invocation Process
================================================

To invoke BASH you can type:

     bash [-acefhiknstuvx] [OPTIONS]

where OPTIONS represents one of the multi-character options described a bit later in this section.  BASH interprets the following single-character options when it is invoked:

a
     Automatically mark variables which are modified or created for export.

c STRING
     Commands are read from STRING.

e
     Exit immediately if a command exits with a nonzero status.

f
     Disable pathname generation.

h
     Locate and remember function commands as functions are defined.

i
     This makes the shell interactive.

k
     Place all keyword arguments for a command in the environment for that command (not just those arguments that precede the command name).

n
     Read commands but don't execute them.

s
     If this option is present, or if no arguments remain after option processing, commands are read from the standard input.  (This option allows the positional parameters to be set when invoking an interactive shell.)

t
     Exit after reading and executing one command.

u
     Treat unset variables as an error when performing parameter expansion.

v
     Print shell input lines as they are read.

x
     After expanding each command, display the value of PS4 followed by the command and its expanded arguments.

BASH also interprets a number of multi-character options.  These options must appear on the command line before the single-character options in order to be recognized.  These options are:

-norc
     Do not load the personal initialization file ~/.bashrc.  This is the default if the shell name is sh.

-noprofile
     Do not read either /etc/profile or ~/.bash_profile, if this is a login shell.

-rcfile FILE
     Execute commands from FILE instead of from the standard personal initialization file ~/.bashrc.

-version
     Show the version number of this instance of BASH when starting.

-quiet
     Do not be verbose when starting up (do not show the shell version or any other information).

-login
     Make BASH act as if it had been invoked by login.

-nobraceexpansion
     Do not perform curly brace expansion (see Grouping).

-nolineediting
     Do not use the readline library to read command lines if this shell is interactive.

If arguments remain after option processing, and neither the -c nor the -s option has been supplied, then the first argument is assumed to be the name of a file containing shell commands. If BASH is invoked in this fashion, the variable 0 is set to the name of the file, and the positional parameters are set to the remaining arguments. BASH reads and executes commands from this file, then exits.

How BASH Handles Signals
========================

When BASH is interactive, it ignores SIGTERM.  This means that kill 0 will not kill an interactive shell.  Also, SIGINT is caught and ignored, so that wait is interruptible.

In all cases, BASH ignores SIGQUIT.

If job control is in effect, bash ignores SIGTTIN, SIGTTOU, and SIGTSTP.  Synchronous jobs started by BASH have signals set to the values inherited by the shell from its parent. Background jobs (jobs started with &) ignore SIGINT and SIGQUIT.

Commands run as a result of command substitution ignore the keyboard-generated job control signals SIGTTIN, SIGTTOU, and SIGTSTP.

Here's a description of the signals listed above:

SIGINT
     This is the signal generated (normally) by C-c on the keyboard. This signal will kill most processes, although a program may choose to ignore SIGINT.  SIGINT also allows a process to clean up after itself before dying.

SIGQUIT
     This is the signal generated (normally) by C-\ on the keyboard. SIGQUIT is identical to SIGINT except that it requests that the operating system produce a diagnostics file (called a core dump which is placed into a file named core).

SIGTERM
     SIGTERM is similar to SIGINT except that it is normally produced by a software program and not from the C-c on the keyboard.  Note that some programs treat SIGTERM differently from SIGINT.

SIGTSTP
     SIGTSTP is the signal sent (normally) by the C-z key on the keyboard.  Some programs may ignore this signal.  This signal does not kill the process but instead stops the process, putting the program into a suspended state.

SIGTTIN
     The kernel sends the signal SIGTTIN to a job/process group that is not in the foreground (that is, the process group's process group ID is not equal to the terminal's foreground process group ID) and attempts to read from the terminal.

SIGTTOU
     The kernel sends the signal SIGTTOU to a job/process group that is not in the foreground and attempts to write to the terminal if, and only if, the terminal has the TOSTOP bit set in its local flags word (you can set this bit with stty tostop).

Command Processing
******************

Word Splitting and Pathname Expansion
=====================================

The shell scans the results of parameter expansion and command substitution that did not occur within double quotes for word splitting.

The shell treats each character of the variable IFS as a delimiter, and splits the results of the other expansions into words on these characters.  The default value of IFS is exactly <space><TAB><newline>. See Shell Vars, for more information on how to change the value of IFS.

If IFS is unset or null, no splitting is done.  Otherwise, each occurrence of an IFS character is treated as a delimiter.

Explicit null arguments ("" or '' -- i.e., single or double quotes with nothing between them) are retained. Implicit null arguments, resulting from the expansion of parameters that have no values, are removed.  If no expansion occurs, then no splitting is performed.

After word splitting, BASH scans each word for the special characters *, ?, and [...], unless the -f option is present.  If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of pathnames matching the pattern.  See File Names, for more information on these special characters.

If no matching pathnames are found, and the shell variable allow_null_glob_expansion is unset, the word is left unchanged (see Shell Vars).  If the variable is set, the word is removed if no matches are found.

When a pattern is used for pathname generation, the character . (at the start of a name or immediately following a slash) must be matched explicitly, unless the shell variable glob_dot_filenames is set (see Shell Vars).  The slash character must always be matched explicitly.  In other cases, the . character is not treated specially.

Sample Script Files
*******************

When you first log in, a shell process is started that establishes the environment for your session (see Invoke Order).  A system-wide login script assigns default values to environment variables creating a basic, default environment (see Environment). (A login script is simply a file that contains commands that customize the environment.)

This default environment can be quite restrictive.  BASH uses various local login scripts to allow you to change and ``personalize'' the default environment (see Invoke Order).  If a local login scripts exists, it is executed by the shell before you get a shell prompt, customizing your environment for you.

Login Scripts
=============

A local login script allows you to change the default environment to fit your needs.  If you have one it resides in your home directory. Note that names for this script begin with a dot (.), so the file remains hidden when performing a standard directory listing (ls).  You have to type ls -a to see if you have any local login scripts.  If you do, it will be called one of the following names:

~/.bash_profile

~/.bash_login

~/.profile

Since this file contains start-up instructions for your account, you can modify this file to create an environment specific to your needs.  Here is an example of a BASH start-up file for login shells, ~/.bash_profile:

     # File: /usr/gnu/lib/Bash_profile

     # Startup file for bash login shells.
     #
     default_dir=/usr/gnu/lib/

     # Test to see if this is an interactive shell.
     if [ "$PS1" ]; then
       PS1='\u@\h(\#)\$ ' KELLEM added \ before $
       ignoreeof=3
     fi

     LOGIN_SHELL=true

     # If the user has her own init file, then use that one, else use
     # the canonical one.
     if [ -f ~/.bashrc ]; then
       source ~/.bashrc
     else if [ -f ${default_dir}Bashrc ]; then
       source ${default_dir}Bashrc;
       fi
     fi

Logout Scripts
==============

A logout script allows you to automate a variety of tasks like starting background processes with a nohup option, running file clean-up routines, or simply displaying a logout message when you log out.  If a .bash_logout file exits in your home directory, it is executed automatically when you log out.

The logout script can contain any commands that you might type at the shell prompt.  However, a logout script is most useful when used to display information about the session just ending and to run background commands after you log out.

Here's an example of a simple BASH logout file, ~/.bash_logout:

     # File: /usr/close/.bash_logout
     # BASH log off file

     # First clear the screen.
     clear

     # Clean up my files.
     echo "cleaning things up now"
     rm *.o

     # Print a logout message.
     echo `whoami` "logged out on" `date`

     # Then say goodbye.
     echo "Au revoir"

Non-login, Interactive Scripts
==============================

All login scripts are run when you first log in. In addition, login scripts that end in rc are executed each time your current shell creates a subshell. Here's an example of a BASH start-up file for non-login, interactive shells, ~/.bashrc:

     # File: /usr/gnu/lib/Bashrc
     # Bourne Again SHell init file.
     #
     # Files you make look like rw-rw-r
     umask 002

     # Don't make useless coredump files.  If you want a coredump,
     # say "ulimit -c unlimited" and then cause a segmentation fault.
     ulimit -c 0

     # Sometimes, there are lots of places that one can find tex
     # inputs.
     export TEXINPUTS=.:$HOME/bin:/usr/lib/tex/inputs:/usr/local/lib/tex/inputs

     # Where's the Gnu stuff at?
     GNU=/usr/gnu/bin
     X11=/usr/bin/X11

     UTIL_PATH=$GNU:$X11
     STANDARD_PATH=/usr/local/bin:/usr/ucb:/bin:/usr/bin:/usr/etc:/etc:/usr/games
     if [ "$HOSTTYPE" = "sony" ]; then STANDARD_PATH=$STANDARD_PATH:/usr/sony/bin; fi

     if [ -d $HOME/bin/$HOSTTYPE ]; then
       MY_PATH=$HOME/bin/$HOSTTYPE
     fi

     if [ -d $HOME/bin ]; then
       MY_PATH=$MY_PATH:$HOME/bin
     fi

     PATH=.:$MY_PATH:$UTIL_PATH:$STANDARD_PATH

     # If running interactively, then:
     if [ "$PS1" ]; then

       # Here are a couple of functions to make csh user's lives easier.
       setenv () {
         export $1="$2"
       }

       unsetenv () {
         unset $*
       }

       # Here are a couple of functions that make *my* life easier.
       showme () {
         local files=$(type -all -path $1)
         if [ "$files" ]; then ls -l $files; else echo "No such file."; fi
       }

       # Set ignoreeof if you don't want EOF as the sole input to the shell to
       # immediately signal a quit condition.  This only happens at the start
       # of a line if the line is empty, and you haven't just deleted a character
       # with C-d.  I turn this on in ~/.bash_profile so that only login shells
       # have the right to be obnoxious.
       # ignoreeof=

       # Set auto_resume if you want TWENEX style behavior for command names.
       auto_resume=

       # Set notify if you want to be asynchronously notified about background
       # job completion.
       notify=

       # Make it so that failed `exec' commands don't flush this shell.
       no_exit_on_failed_exec=

       if [ ! "$LOGIN_SHELL" ]; then
         PS1="\u@\h\$ "
       fi

       HISTSIZE=256
       MAILCHECK=60

       # A couple of default aliases.
       alias j='jobs -l'
       alias po=popd
       alias pu=pushd
       alias ls='ls -F'

     HOST=$(hostname | sed -e 's/\.*//')

     xtitle () { echo -n -e "\033]l$*\033" }

       if [ -f ~/.bash_aliases ]; then
         source ~/.bash_aliases
       fi
     fi

Writing and Debugging Scripts
*****************************

When writing scripts, it's always possible that mistypings and other errors can occur.  In complicated scripts errors may be difficult to track down and fix.

The shell can make things simpler though, with its debugging options, like -v and -x.  All can be invoked by command arguments to BASH or through the set command (see Built-in).  For example, bash -v or set -v.

The -v option sets the shell to verbose mode.  This causes command lines to be displayed as they are read. This is useful for finding syntax errors.  You can use this option in conjunction with the -n option, which prevents the execution of commands. However, note that saying set -n makes a terminal useless until an end-of-file is typed.

The -x option displays each command as it is executed, following all substitutions. This lets you see what is going on as the shell program runs. It shows you what the shell did to your command line as a result of all the substitutions that took place.  This is useful to see if your command lines do what you wanted them to do.

In long shell scripts you can get lots of unwanted and unnecessary debugging information from the shell when the -x option is used.  You can reduce the amount of output by turning this option on (set -x) where you need it and turning it off (set +x) when you don't.

Adding echo statements to the shell script also helps when debugging.  It's like having print statments in a program.

You can even check for unset shell variables with the -u option. When you use this option, attempts to substitute variables that have not been set causes an error message and execution is stopped.

The current setting of the shell options is available as $-.

More Examples of Shell Scripts
==============================

Here's an example of a more advanced shell script. This script tells you which file will be executed when you use the command you give it as an argument.  It uses sed to split your path, inserting dots in place of null strings to preserve the shell semantics.  It tests each directory on your path for an executable file whose name is the same as the argument you gave to the script.  If it finds one, it tells you what it is and exits with a successful status.  If no executable files are found, the script exits with a failure status.

     #
     # which -- find out which command in $PATH is executed
     #
     # adapted from Kernighan and Pike
     #
     opath=$PATH
     PATH=/usr/ucb:/bin:/usr/bin

     case $# in
         0)
          echo "usage: $0 command" 1>&2
          exit 1
          ;;
         *)
          ;;
     esac

     for i in $(echo $opath | sed 's/^:/.:/
                          s/::/:.:/g
                          s/$:/:./
                          s/:/ /g')
     do
          if [ -x $i/$1 ] ; then
               echo $i/$1
               exit 0
          fi
     done
     exit 1

Here's another example, submitted by Bennett Todd (bet@orion.mc.duke.edu).  It forces the commands run as the arguments to the script to die after some timeout. This is handy for debugging full-screen programs (like Emacs) that, if they get hung, wedge the terminal fatally.

     #!/bin/sh
     # Launch a sleeping killer-offer

     progname=`basename $0`
     timeout=10
     signal=TERM

     while test $# -gt 2 -a `expr "x$1" : "x-."` -gt 0
     do
          case "x$1"
          in
               x-t) shift; timeout=$1; shift;;
               x-s) shift;  signal=$1; shift;;
          esac
     done

     if test $# -lt 1
     then
          echo "syntax: $0 [-t timeout] [-s signal] command" 1>&2
          exit 1
     fi

     (sleep $timeout; kill -$signal $$) &
     exec "$@"

Finally, here's one more example of a shell script, submitted by Bill Trost (trost@reed.bitnet).  It creates an extended version of the shell's pushd & popd commands.  It's slower than the built-ins, but also adds a couple of features to pushd: negative numeric arguments (given a dirstack of size 3, pushd +2 is equivalent to pushd -1), and named references.  With a named reference, a command of the form pushd +xterm will rotate the directory stack to the first directory whose final component is xterm.  It uses the # variable construct, and lots of sets and shifts.

     # A shell-level version of pushd and popd.  A bit slower, a bit
     # cleverer.  I added a feature, which is best described by
     # example.
     # Suppose you have the directory stack consisting of /tmp,
     # /local/src/X11r4/mit/clients/xterm, and ~/prj/term (/tmp at the
     # top).  If you type "pushd +xterm", you'll end up in the first
     # directory whose name end with "xterm".

     # This is a complete rewrite of a similar function posted to
     # gnu.bash.bug by Martin Tomes <mt00@eurotherm.co.uk>.  I've done
     # a little benchmarking, and this version's pushd appears to be
     # gobs faster; this is probably due to my use of the case
     # construct instead of if/elif/fi.  The if construct (at least in
     # Bourne shell) has historically been very slow.  Then again,
     # popd was just as fast...?
     # The alternative explanation is that his frequent use of the
     # "cut" and "expr" commands slowed things down.

     # This program expects the "seq" command to give a sequence of
     # numbers from $1 to $2.  I have a "seq" function which is
     # usually very fast.

     dirs () { echo $PWD $DIRS }

     pushd () {
       case "$1" in
         "")
             # Swap first two.
             local here=$PWD
             set $DIRS
             cd "$1"
             shift
             DIRS="$here $*"
             ;;
         +[0-9]*)
             local save i=${1#+}
             set $PWD $DIRS
             for i in `seq 1 $i`; do
               [ "$1" = "" ] && { set $PWD $DIRS ; save= }
               save="$save $1"
               shift
             done
             [ "$1" = "" ] || {
               cd $1
               shift
               DIRS="$* $save"
             }
             ;;
         [-][0-9]*)
             local dest=${1#-}
             set $PWD $DIRS
             pushd +`expr $# -  \\( $dest % $# \\)`
             ;;
         +?*)
             # Feature: pushd +foo will push to directory whose
             # basename is "foo".
             local wrap i goal=${1#+} found=false
             set $PWD $DIRS
             for i; do
               [ ${i##*/} = "$goal" ] && {
                 cd $i
                 shift
                 DIRS="$* $wrap"
                 found=true
                 break
               }
               wrap="$wrap $i"
               shift
             done
             $found || {
               echo ${goal}: Directory not on stack. 1>&2
               return 1
             }
             ;;
         *)
             [ ! -d $1 ] && {
               echo "$1": No such file or directory 1>&2
               return 1
             }
             DIRS="$PWD $DIRS"
             cd $1
             ;;
       esac
       true ${pushd_silent:-`dirs`}
     }

     popd () {
       [ -z "$DIRS" ] && {
         echo popd: Directory stack empty 1>&2
         return 1
       }
       case "$1" in
         "")
             set $DIRS
             cd $1
             shift
             DIRS="$*"
             ;;
         +*)
             count=$1
             set $DIRS
             # Hack until builtin test works correctly with unary +
             /bin/[ $count -gt $# ] && {
               echo popd: Directory stack not that deep 1>&2
               return 1
             }
             DIRS="`echo $DIRS | awk '{ $'$count' = \"\"; print }'`"
             ;;
         *)
             echo 'popd: usage: popd [ +n ]' 1>&2
             return 1
             ;;
       esac
       true ${pushd_silent:-`dirs`}
     }

Useful Operating System Programs
********************************

This is the section that will include useful and related operating system commands (NOT built-ins) to use with the shell and shell procedures.

If you think that various utilities and commands used to support shell programming belong in the shell programming manual, then go ahead and add them yourself.  Personally, I feel that there is no good determiner of whether a utility belongs in the shell programming manual or whether it belongs in the GNU operating system manual.

Who and Where to Write
**********************

This manual is a combined effort of a number of people.  Diane Barlow Close (close@lunch.wpd.sgi.com) wrote the original draft.  Julie Sussman (jems@altdorf.lcs.mit.edu) did the majority of reorganization and the second draft.  Without her help, this manual would probably still be waiting to be written.  Brian Fox (bfox@ai.mit.edu) produced the third draft, and provided technical advice for Diane and Julie.

Chet Ramey (chet@cwns1.ins.cwru.edu) provided many examples for this manual and wrote the BASH man page.

Richard Stallman (rms@ai.mit.edu) provided editing and polishing of the finished product.

Others who provided assistance of varying degrees are mentioned in the acknowledgement section (see Thanks).

Errors concerning this documentation should be sent to bug-bash-manual@ai.mit.edu.  See Bugs, for information on where to send bug reports for BASH itself.