BUY THIS BOOK

Safari Books Online

What is this?

Looking to Reprint this content?


Learning the bash Shell
Learning the bash Shell, Second Edition

By Cameron Newham, Bill Rosenblatt

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: bash Basics
Since the early 1970s, when it was first created, the UNIX operating system has become more and more popular. During this time it has branched out into different versions, and taken on such names as Ultrix, AIX, Xenix, SunOS, and Linux. Starting on minicomputers and mainframes, it has moved onto desktop workstations and even personal computers used at work and home. No longer a system used only by academics and computing wizards at universities and research centers, UNIX is used in many businesses, schools, and homes. As time goes on, more people will come into contact with UNIX.
You may have used UNIX at your school, office, or home to run your applications, print documents, and read your electronic mail. But have you ever thought about the process that happens when you type a command and hit RETURN?
Several layers of events take place whenever you enter a command, but we're going to consider only the top layer, known as the shell. Generically speaking, a shell is any user interface to the UNIX operating system, i.e., any program that takes input from the user, translates it into instructions that the operating system can understand, and conveys the operating system's output back to the user. Figure 1.1 shows the relationship between user, shell, and operating system.
Figure 1.1: The shell is a layer around the UNIX operating system
There are various types of user interfaces. bash belongs to the most common category, known as character-based user interfaces. These interfaces accept lines of textual commands that the user types in; they usually produce text-based output. Other types of interfaces include the increasingly common graphical user interfaces (GUI), which add the ability to display arbitrary graphics (not just typewriter characters) and to accept input from a mouse or other pointing device, touch-screen interfaces (such as those on some bank teller machines), and so on.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What Is a Shell?
The shell's job, then, is to translate the user's command lines into operating system instructions. For example, consider this command line:
sort -n phonelist > phonelist.sorted
This means, "Sort lines in the file phonelist in numerical order, and put the result in the file phonelist.sorted." Here's what the shell does with this command:
  1. Breaks up the line into the pieces sort, -n, phone list, >, and phone list.sorted. These pieces are called words.
  2. Determines the purpose of the words: sort is a command, -n and phone list are arguments, and > and phonelist.sorted, taken together, are I/O instructions.
  3. Sets up the I/O according to > phonelist.sorted (output to the file phone list.sorted) and some standard, implicit instructions.
  4. Finds the command sort in a file and runs it with the option -n (numerical order) and the argument phonelist (input filename).
Of course, each of these steps really involves several substeps, each of which includes a particular instruction to the underlying operating system.
Remember that the shell itself is not UNIX—just the user interface to it. UNIX is one of the first operating systems to make the user interface independent of the operating system.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Scope of This Book
In this book you will learn about bash, which is one of the most recent and powerful of the major UNIX shells. There are two ways to use bash: as a user interface and as a programming environment.
This chapter and the next cover interactive use. These two chapters should give you enough background to use the shell confidently and productively for most of your everyday tasks.
After you have been using the shell for a while, you will undoubtedly find certain characteristics of your environment (the shell's "look and feel") that you would like to change, and tasks that you would like to automate. Chapter 3 shows several ways of doing this.
Chapter 3, also prepares you for shell programming, the bulk of which is covered in Chapter 4 through Chapter 6. You need not have any programming experience to understand these chapters and learn shell programming. Chapter 7 and Chapter 8 give more complete descriptions of the shell's I/O and process handling capabilities, while Chapter 9, discusses various techniques for debugging shell programs.
You'll learn a lot about bash in this book; you'll also learn about UNIX utilities and the way the UNIX operating system works in general. It's possible to become a virtuoso shell programmer without any previous programming experience. At the same time, we've carefully avoided going into excessive detail about UNIX internals. We maintain that you shouldn't have to be an internals expert to use and program the shell effectively, and we won't dwell on the few shell features that are intended specifically for low-level systems programmers.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
History of UNIX Shells
The independence of the shell from the UNIX operating system per se has led to the development of dozens of shells throughout UNIX history—although only a few have achieved widespread use.
The first major shell was the Bourne shell (named after its inventor, Steven Bourne); it was included in the first popular version of UNIX, Version 7, starting in 1979. The Bourne shell is known on the system as sh. Although UNIX has gone through many, many changes, the Bourne shell is still popular and essentially unchanged. Several UNIX utilities and administration features depend on it.
The first widely used alternative shell was the C shell, or csh. This was written by Bill Joy at the University of California at Berkeley as part of the Berkeley Software Distribution (BSD) version of UNIX that came out a couple of years after Version 7. It's included in most recent UNIX versions.
The C shell gets its name from the resemblance of its commands to statements in the C Programming Language, which makes the shell easier for programmers on UNIX systems to learn. It supports a number of operating system features (e.g., job control; see Chapter 8) that were unique to BSD UNIX but by now have migrated to most other modern versions. It also has a few important features (e.g., aliases; see Chapter 3) that make it easier to use in general.
In recent years a number of other shells have become popular. The most notable of these is the Korn shell. This shell is a commercial product that incorporates the best features of the Bourne and C shells, plus many features of its own. The Korn shell is similar to bash in most respects; both have an abundance of features that make them easy to work with. The advantage of bash is that it is free. For further information on the Korn shell see Appendix A.
The Bourne Again shell (named in punning tribute to Steve Bourne's shell) was created for use in the GNU project. The GNU project was started by Richard Stallman of the Free Software Foundation (FSF) for the purpose of creating a UNIX-compatible operating system and replacing all of the commercial UNIX utilities with freely distributable ones. GNU embodies not only new software utilities, but a new distribution concept: the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Getting bash
You may or may not be using bash right now. Your system administrator probably set your account up with whatever shell he or she uses as the "standard" on the system. You may not even have been aware that there is more than one shell available.
Yet it's easy for you to determine which shell you are using. Log in to your system and type echo $SHELL at the prompt. You will see a response containing sh, csh, ksh, or bash; these denote the Bourne, C, Korn, and bash shells, respectively. (There's also a chance that you're using another shell such as tcsh.)
If you aren't using bash and you want to, then you first need to find out if it exists on your system. Just type bash. If you get a new prompt consisting of some information followed by a dollar-sign (e.g: bash2-2.01$ ), then all is well; type exit to go back to your normal shell.
If you get a "not found" message, your system may not have it. Ask your system administrator or another knowledgeable user; there's a chance that you might have some version of bash installed on the system in a place (directory) that is not normally accessible to you. If not, read Chapter 11, to find out how you can obtain a version of bash.
Once you know you have bash on your system, you can invoke it from whatever other shell you use by typing bash as above. However, it's much better to install it as your login shell, i.e., the shell that you get automatically whenever you log in. You may be able to do the installation by yourself. Here are instructions that are designed to work on the widest variety of UNIX systems. If something doesn't work (e.g., you type in a command and get a "not found" error message or a blank line as the response), you'll have to abort the process and see your system administrator or, alternatively, turn to Chapter 11 where we demonstrate a less straightforward way of replacing your current shell.
You need to find out where bash is on your system, i.e., in which directory it's installed. You might be able to find the location by typing
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Interactive Shell Use
When you use the shell interactively, you engage in a login session that begins when you log in and ends when you type exit or logout or press CTRL-D. During a login session, you type in command lines to the shell; these are lines of text ending in RETURN that you type in to your terminal or workstation.
By default, the shell prompts you for each command with an information string followed by a dollar sign, though as you will see in Chapter 3, the entire prompt can be changed.
Shell command lines consist of one or more words, which are separated on a command line by blanks or TABs. The first word on the line is the command. The rest (if any) are arguments (also called parameters) to the command, which are names of things on which the command will act.
For example, the command line lp myfile consists of the command lp (print a file) and the single argument myfile. lp treats myfile as the name of a file to print. Arguments are often names of files, but not necessarily: in the command line mail cam, the mail program treats cam as the username to which a message will be sent.
An option is a special type of argument that gives the command specific information on what it is supposed to do. Options usually consist of a dash followed by a letter; we say "usually" because this is a convention rather than a hard-and-fast rule. The command lp -h myfile contains the option -h, which tells lp not to print the "banner page" before it prints the file.
Sometimes options take their own arguments. For example, lp -d lp1 -h myfile has two options and one argument. The first option is -d lp1, which means "Send the output to the printer (destination) called lp1." The second option and argument are the same as in the previous example.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Files
Although arguments to commands aren't always files, files are the most important types of "things" on any UNIX system. A file can contain any kind of information, and indeed there are different types of files. Three types are by far the most important:
Regular files
Also called text files; these contain readable characters. For example, this book was created from several regular files that contain the text of the book plus human-readable formatting instructions to the troff word processor.
Executable files
Also called programs; these are invoked as commands. Some can't be read by humans; others—the shell scripts that we'll examine in this book—are just special text files. The shell itself is a (non-human-readable) executable file called bash.
Directories
These are like folders that contain other files—possibly other directories (called subdirectories).
Let's review the most important concepts about directories. The fact that directories can contain other directories leads to a hierarchical structure, more popularly known as a tree, for all files on a UNIX system.
Figure 1.2 shows part of a typical directory tree; rectangles are directories and ovals are regular files.
Figure 1.2: A tree of directories and files
The top of the tree is a directory called root that has no name on the system. All files can be named by expressing their location on the system relative to
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Input and Output
The software field—really, any scientific field—tends to advance most quickly and impressively on those few occasions when someone (i.e., not a committee) comes up with an idea that is small in concept yet enormous in its implications. The standard input and output scheme of UNIX has to be on the short list of such ideas, along with such classic innovations as the LISP language, the relational data model, and object-oriented programming.
The UNIX I/O scheme is based on two dazzlingly simple ideas. First, UNIX file I/O takes the form of arbitrarily long sequences of characters (bytes). In contrast, file systems of older vintage have more complicated I/O schemes (e.g., "block," "record," "card image," etc.). Second, everything on the system that produces or accepts data is treated as a file; this includes hardware devices like disk drives and terminals. Older systems treated every device differently. Both of these ideas have made systems programmers' lives much more pleasant.
By convention, each UNIX program has a single way of accepting input called standard input, a single way of producing output called standard output, and a single way of producing error messages called standard error output, usually shortened to standard error. Of course, a program can have other input and output sources as well, as we will see in Chapter 7.
Standard I/O was the first scheme of its kind that was designed specifically for interactive users at terminals, rather than the older batch style of use that usually involved decks of punch-cards. Since the UNIX shell provides the user interface, it should come as no surprise that standard I/O was designed to fit in very neatly with the shell.
All shells handle standard I/O in basically the same way. Each program that you invoke has all three standard I/O channels set to your terminal or workstation, so that standard input is your keyboard, and standard output and error are your screen or window. For example, the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Background Jobs
Pipes are actually a special case of a more general feature: doing more than one thing at a time. This is a capability that many other commercial operating systems don't have, because of the rigid limits that they tend to impose upon users. UNIX, on the other hand, was developed in a research lab and meant for internal use, so it does relatively little to impose limits on the resources available to users on a computer—as usual, leaning towards uncluttered simplicity rather than overcomplexity.
"Doing more than one thing at a time" means running more than one program at the same time. You do this when you invoke a pipeline; you can also do it by logging on to a UNIX system as many times simultaneously as you wish. (If you try that on an IBM's VM/CMS system, for example, you will get an obnoxious "already logged in" message.)
The shell also lets you run more than one command at a time during a single login session. Normally, when you type a command and hit RETURN, the shell will let the command have control of your terminal until it is done; you can't type in further commands until the first one is done. But if you want to run a command that does not require user input and you want to do other things while the command is running, put an ampersand (&) after the command.
This is called running the command in the background, and a command that runs in this way is called a background job; by contrast, a job run the normal way is called a foreground job. When you start a background job, you get your shell prompt back immediately, enabling you to enter other commands.
The most obvious use for background jobs is programs that take a long time to run, such as sort or uncompress on large files. For example, assume you just got an enormous compressed file loaded into your directory from magnetic tape. Let's say the file is gcc.tar.Z, which is a compressed archive file that contains well over 10 MB of source code files.
Type uncompress gcc.tar &
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Special Characters and Quoting
The characters <, >, |, and & are four examples of special characters that have particular meanings to the shell. The wildcards we saw earlier in this chapter (*, ?, and [...]) are also special characters.
Table 1.6 gives the meanings of all special characters within shell command lines only. Other characters have special meanings in specific situations, such as the regular expressions and string-handling operators that we'll see in Chapter 3 and Chapter 4.
Table 1.6: Special Characters
Character Meaning See Chapter
~ Home directory1
` Command substitution (archaic)4
# Comment4
$ Variable expression3
& Background job1
* String wildcard1
( Start subshell8
) End subshell8
\ Quote next character1
| Pipe1
[ Start character-set wildcard1
] End character-set wildcard1
{ Start command block7
} End command block7
; Shell command separator3
' Strong quote1
<"> Weak quote1
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Help
A feature in bash that no other shell has is an online help system. The help command gives information on commands in bash. If you type help by itself, you'll get a list of the built-in shell commands along with their options.
If you provide help with a shell command name it will give you a detailed description of the command:
$ help cd
cd: cd [-PL] [dir]
    Change the current directory to DIR.  The variable $HOME is the
    default DIR.  The variable $CDPATH defines the search path for
    the directory containing DIR.  Alternative directory names in
    CDPATH are separated by a colon (:).  A null directory name is
    the same as the current directory, i.e. `.'.  If DIR begins with
    a slash (/), then $CDPATH is not used.  If the directory is not
    found, and the shell option `cdable_vars' is set, then try the
    word as a variable name.  If that variable has a value, then cd
    to the value of that variable.  The -P option says to use the
    physical directory structure instead of following symbolic links;
    the -L option forces symbolic links to be followed.
You can also provide help with a partial name, in which case it will return details on all commands matching the partial name. For example, help re will provide details on read, readonly, and return. The partial name can also include wildcards. You'll need to quote the name to ensure that the wildcard is not expanded to a filename. So the last example is equivalent to help 're*', and help 're??' will only return details on read.
Sometimes help will show more than a screenful of information and it will scroll the screen. You can use the more command to show one screenful at a time by typing help command | more.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Command-Line Editing
It's always possible to make mistakes when you type at a computer keyboard, but perhaps even more so when you are using a UNIX shell. UNIX shell syntax is powerful, yet terse, full of odd characters, and not particularly mnemonic, making it possible to construct command lines that are as cryptic as they are complex. The Bourne and C shells exacerbate this situation by giving you extremely limited ways of editing your command lines.
In particular, there is no way to recall a previous command line so that you can fix a mistake. If you are an experienced Bourne shell user, undoubtedly you know the frustration of having to retype long command lines. You can use the BACKSPACE key to edit, but once you hit RETURN, it's gone forever!
The C shell provided a small improvement via its history mechanism, which provides a few very awkward ways of editing previous commands. But there are more than a few people who have wondered, "Why can't I edit my UNIX command lines in the same way I can edit text with an editor?"
This is exactly what bash allows you to do. It has editing modes that allow you to edit command lines with editing commands similar to those of the two most popular UNIX editors, vi and emacs. It also provides a much-extended analog to the C shell history mechanism called fc (for fix command) that, among other things, allows you to use your favorite editor directly for editing your command lines. To round things out, bash also provides the original C shell history mechanism.
In this chapter, we will discuss the features that are common to all of bash's command-history facilities; after that, we will deal with each facility in detail. If you use either vi or emacs, you may wish to read the section on the emulation mode for only the one you use. If you use neither vi or emacs, but are interested in learning one of the editing modes anyway, we suggest emacs-mode, because it is more of a natural extension of the minimal editing capability you get with the bare shell.
We should mention up front that both emacs- and vi-modes introduce the potential for clashes with control keys set up by the UNIX terminal interface. Recall the control keys shown in Chapter 1, in Table 1.7 and the sample
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Enabling Command-Line Editing
bash initially starts interactively with emacs-mode as the default (unless you have started bash with the -noediting option; see Chapter 10). There are two ways to enter either editing mode while in the shell. First, you can use the set command:
$ set -o emacs
         
or:
$ set -o vi
         
The second way of selecting the editing mode is to set a readline variable in the file .inputrc. We will look at this method later in this chapter.
You will find that the vi- and emacs-editing modes are good at emulating the basic commands of these editors, but not their advanced features; their main purpose is to let you transfer "keyboard habits" from your favorite editor to the shell. fc is quite a powerful facility; it is mainly meant to supplant C shell history and as an "escape hatch" for users of editors other than vi or emacs. Therefore the section on fc is mainly recommended to C shell users and those who don't use either standard editor.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The History File
All of bash's command history facilities depend on a list that records commands as you type them into the shell. Whenever you log in or start another interactive shell, bash reads an initial history list from the file .bash_history in your home directory. From that point on, every bash interactive session maintains its own list of commands. When you exit from a shell, it saves the list in .bash_history. You can call this file whatever you like by setting the environment variable HISTFILE. We'll look more closely at HISTFILE and some other related command history variables in the next chapter.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
emacs Editing Mode
If you are an emacs user, you will find it most useful to think of emacs editing mode as a simplified emacs with a single, one-line window. All of the basic commands are available for cursor motion, cut-and-paste, and search.
emacs-mode uses control keys for the most basic editing functions. If you aren't familiar with emacs, you can think of these as extensions of the rudimentary "erase" character (usually BACKSPACE or DEL) that UNIX provides through its interface to users' terminals. For the sake of consistency, we'll assume your erase character is DEL from now on; if it is CTRL-H or something else, you will need to make a mental substitution. The most basic control-key commands are shown in Table 2.1. (Important: remember that typing CTRL-D when your command line is empty may log you off!) The basic keyboard habits of emacs-mode are easy to learn, but they do require that you assimilate a couple of concepts that are peculiar to the emacs editor.
Table 2.1: Basic emacs-Mode Commands
Command Description
CTRL-BMove backward one character (without deleting)
CTRL-FMove forward one character
DELDelete one character backward
CTRL-DDelete one character forward
The first of these is the use of CTRL-B and CTRL-F for backward and forward cursor motion. These keys have the advantage of being obvious mnemonics. You can also use the left and right cursor motion keys ("arrow" keys), but for the rest of this discussion we will use the control keys, as they work on all keyboards. In emacs-mode, the point (sometimes also called dot) is an imaginary place just to the left of the character the cursor is on. In the command descriptions in Table 2.1, some say "forward" while others say "backward." Think of forward as "to the right of point" and backward as "to the left of point."
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
vi Editing Mode
Like emacs-mode, vi-mode essentially creates a one-line editing window into the history file. vi-mode is popular because vi is the most standard UNIX editor. But the function for which vi was designed, writing C programs, has different editing requirements from those of command interpreters. As a result, although it is possible to do complex things in vi with relatively few keystrokes, the relatively simple things you need to do in bash sometimes take too many keystrokes.
Like vi, vi-mode has two modes of its own: input and control mode. The former is for typing commands (as in normal bash use); the latter is for moving around the command line and the history file. When you are in input mode, you can type commands in and hit RETURN to run them. In addition, you have minimal editing capabilities via control characters, which are summarized in Table 2.7.
Table 2.7: Editing Commands in vi Input Mode
Command Description
DELDelete previous character
CTRL-WErase previous word (i.e., erase until a blank)
CTRL-VQuote the next character
ESCEnter control mode (see below)
Note that at least some of these—depending on which version of UNIX you have—are the same as the editing commands provided by UNIX through its terminal interface. vi-mode will use your "erase" character as the "delete previous character" key; usually it is set to DEL or CTRL-H (BACKSPACE). CTRL-V works the same way as in emacs-mode; it causes the next character to appear in the command line as is and lose its special meaning.
Under normal circumstances, you just stay in input mode. But if you want to go back and make changes to your command line, or if you want to recall previous commands, you need to go into control mode. To do this, hit ESC.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The fc Command
fc is a built-in shell command that provides a superset of the C shell history mechanism. You can use it to examine the most recent commands you entered, to edit one or more commands with your favorite "real" editor, and to run old commands with changes without having to type the entire command in again. We'll look at each of these uses in turn.
The -l option to fc lists previous commands. It takes arguments that refer to commands in the history file. Arguments can be numbers or alphanumeric strings; numbers refer to the commands in the history file, while strings refer to the most recent command beginning with the string. fc treats arguments in a rather complex way:
  • If you give two arguments, they serve as the first and last commands to be shown.
  • If you specify one number argument, only the command with that number is shown.
  • With a single string argument, it searches for the most recent command starting with that string and shows you everything from that command to the most recent command.
  • If you specify no arguments, you will see the last 16 commands you entered. bash also has a built-in command for displaying the history: history.
A few examples should make these options clearer. Let's say you logged in and entered these commands:
            ls -l
            more myfile
            vi myfile
            wc -l myfile
            pr myfile | lp -h
         
If you type fc -l with no arguments, you will see the above list with command numbers, as in:
1	ls -l
2	more myfile
3	vi myfile
4	wc -l myfile
5	pr myfile | lp -h
Adding another option, -n, suppresses the line numbers. If you want to see only commands 2 through 4, type fc -l 2 4. If you want to see only the vi command, type fc -l 3. To see everything from the vi command up to the present, type
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
History Expansion
If you are a C shell user, you may be familiar with the history expansion mechanism that it provides. bash provides a similar set of features. History expansion is a primitive way to recall and edit commands in the history list. The way to recall commands is by the use of event designators. Table 2.15 gives a complete list.
Table 2.15: Event Designators
Command Description
! Start a history substitution
!! Refers to the last command
! n Refers to command line n
!- n Refers to the current command line minus n
! string Refers to the most recent command starting with string
!? string?
Refers to the most recent command containing string. The ending ? is optional
^ string1^string2
Repeat the last command, replacing string1 with string2
By far the most useful command is !!. Typing !! on the command line re-executes the last command. If you know the command number of a specific command, you can use the !n form, where n is the command number. Command numbers can be determined from the history command. Alternatively, you can re-execute the most recent command beginning with the specified string by using !
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
readline
bash's command-line editing interface is readline. It is actually a library of software developed for the GNU project that can be used by applications requiring a text-based interface. It provides editing and text-manipulation features to make it easier for the user to enter and edit text. Just as importantly, it allows standardization, in terms of both key strokes and customization methods, across all applications that use it.
readline provides default editing in either of two modes: vi or emacs. Both modes provide a subset of the editing commands found in the full editors. We've already looked at the command sets of these modes in the previous sections of this chapter. We'll now look at how you can make your own command sets.
readline gives bash added flexibility compared to other shells because it can be customized through the use of key bindings, either from the command line or in a special startup file. You can also set readline variables. We'll see how you can set up readline using your own startup file now, and then go on to examine how the binding capability can be used from the command line.
The default startup file is called .inputrc and must exist in your home directory if you wish to customize readline. You can change the default filename by setting the environment variable INPUTRC (see Chapter 3 for further information on environment variables).
When bash starts up, it reads the startup file (if there is one) and any settings there come into effect. The startup file is just a sequence of lines that bind a keyname to a macro or readline function name. You can also place comments in the file by preceding any line with a #.
You can use either an English name or a key escape sequence for the keyname. For example, to bind CTRL-T to the movement command for moving to the end of the current line, you could place Control-t: end-of-line in your .inputrc
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Keyboard Habits
In this chapter we have seen that bash provides command-line editing with two modes: vi and emacs. You may be wondering why these two editors were chosen. The primary reason is because vi and emacs are the most widely used editors for UNIX. People who have used either editor will find familiar editing facilities.
If you are not familiar with either of these editors, you should seriously consider adopting emacs-mode keyboard habits. Because it is based on control keys and doesn't require you to think in terms of a "command mode" and "insert mode," you will find emacs-mode easier to assimilate. Although the full emacs is an extremely powerful editor, its command structure lends itself very well to small subsetting: there are several "mini-emacs" editors floating around for UNIX, MS-DOS, and other systems.
The same cannot be said for vi, because its command structure is really meant for use in a full-screen editor. vi is quite powerful too, in its way, but its power becomes evident only when it is used for purposes similar to that for which it was designed: editing source code in C and LISP. As mentioned earlier, a vi user has the power to move mountains in few keystrokes—but at the cost of being unable to do anything meaningful in very few keystrokes. Unfortunately, the latter is most desired in a command interpreter, especially nowadays when users are spending more time within applications and less time working with the shell. In short, if you don't already know vi, you will probably find its commands obscure and confusing.
Both bash editing modes have quite a few commands; you will undoubtedly develop keyboard habits that include just a few of them. If you use emacs-mode and you aren't familiar with the full emacs, here is a subset that is easy to learn yet enables you to do just about anything:
  • For cursor motion around a command line, stick to CTRL-A and CTRL-E for beginning and end of line, and CTRL-F and CTRL-B for moving around.
  • Delete using DEL (or whatever your "erase" key is) and CTRL-D; as with CTRL-F and CTRL-B, hold down to repeat if necessary. Use CTRL-K to erase the entire line.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Customizing Your Environment
An environment is a collection of concepts that express the things a computer system or other set of tools does in terms designed to be understandable and coherent, and a look and feel that is comfortable. For example, your desk at work is an environment. Concepts involved in desk work usually include memos, phone calls, letters, forms, etc. The tools on or in your desk that you use to deal with these things include paper, staples, envelopes, pens, a telephone, a calculator, etc. Every one of these has a set of characteristics that express how you use it; such characteristics range from location on your desk or in a drawer (for simple tools) to more sophisticated things like which numbers the memory buttons on your phone are set to. Taken together, these characteristics make up your desk's look and feel.
You customize the look and feel of your desk environment by putting pens where you can most easily reach them, programming your phone buttons, etc. In general, the more customization you have done, the more tailored to your personal needs—and therefore the more productive—your environment is.
Similarly, UNIX shells present you with such concepts as files, directories, and standard input and output, while UNIX itself gives you tools to work with these, such as file manipulation commands, text editors, and print queues. Your UNIX environment's look and feel is determined by your keyboard and display, of course, but also by how you set up your directories, where you put each kind of file, and what names you give to files, directories, and commands. There are also more sophisticated ways of customizing your shell environment.
This chapter will look at the four most important features that bash provides for customizing your environment.
Special files
The files .bash_profile, .bash_logout, and .bashrc that are read by bash when you log in and out or start a new shell.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The .bash_profile, .bash_logout, and .bashrc Files
Three files in your home directory have a special meaning to bash, providing a way for you to set up your account environment automatically when you log in and when you invoke another bash shell, and allowing you to perform commands when you log out. These files may already exist in your home directory, depending on how your system administrator has set up your account. If they don't exist, your account is using only the default system file /etc/profile. You can easily create your own bash files using your favorite text editor. If you are unfamiliar with text editors available under UNIX, we suggest that you familiarize yourself with one of the better-known ones such as vi or emacs before proceeding further with the techniques described in this chapter.
The most important bash file, .bash_profile, is read and the commands in it executed by bash every time you log in to the system. If you examine your .bash_profile you will probably see lines similar to:
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
SHELL=/bin/bash
MANPATH=/usr/man:/usr/X11/man
EDITOR=/usr/bin/vi

PS1='\h:\w\$ '
PS2='> '
export EDITOR
These lines define the basic environment for your login account. For the moment, it is probably best to leave these lines alone until you understand what they do. When editing your .bash_profile, just add your new lines after the existing ones.
Note that whatever you add to your .bash_profile won't take effect until the file is re-read by logging out and then logging in again. Alternatively, you can also use the source command. For example:
source .bash_profile
source executes the commands in the specified file, in this case .bash_profile, including any commands that you have added.
bash allows two synonyms for .bash_profile: .bash_login, derived from the C shell's file named .login, and .profile, derived from the Bourne shell and Korn shell files named .profile. Only one of these three is read when you log in. If
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Aliases
If you have used UNIX for any length of time you will have noticed that there are many commands available and that some of them have cryptic names. Sometimes the commands you use the most have a string of options and arguments that need to be specified. Wouldn't it be nice if there was a feature that let you rename the commands or allowed you to type in something simple instead of half a dozen options? Fortunately, bash provides such a feature: the alias.
Aliases can be defined on the command line, in your .bash_profile, or in your .bashrc, using this form:
alias name=command
This syntax specifies that name is an alias for command. Whenever you type name as a command, bash will substitute command in its place when it executes the line. Notice that there are no spaces on either side of the equal sign (=); this is the required syntax.
There are a few basic ways to use an alias. The first, and simplest, is as a more mnemonic name for an existing command. Many commonly used UNIX commands have names that are poor mnemonics and are therefore excellent candidates for aliasing, the classic example being:
alias search=grep
grep, the UNIX file-searching utility, was named as an acronym for something like "Generalized Regular Expression Parser." This acronym may mean something to a computer scientist, but not to the office administrator who has to find Fred in a list of phone numbers. If you have to find Fred and you have the word search defined as an alias for grep, you can type:
$ search Fred phonelist
         
Some people who aren't particularly good typists like to use aliases for typographical errors they make often. For example:
alias emcas=emacs
alias mali=mail
alias gerp=grep
This can be handy, but we feel you're probably better off suffering with the error message and getting the correct spelling under your fingers. Another common way to use an alias is as a shorthand for a longer command string. For example, you may have a directory to which you need to go often. It's buried deep in your directory hierarchy, so you want to set up an alias that will allow you to
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Options
While aliases let you create convenient names for commands, they don't really let you change the shell's behavior. Options are one way of doing this. A shell option is a setting that is either "on" or "off." While several options relate to arcane shell features that are of interest only to programmers, those that we will cover here are of interest to all users.
The basic commands that relate to options are set -o optionname and set +o optionname. You can change more than one option with the one set command by preceding each optionname with a -o or +o. The use of plus (+) and minus (-) signs is counterintuitive: the - turns the named option on, while the + turns it off. The reason for this incongruity is that the dash (-) is the conventional UNIX way of specifying options to a command, while the use of + is an afterthought.
Most options also have one-letter abbreviations that can be used in lieu of the set -o command; for example, set -o noglob can be abbreviated set -f. These abbreviations are carryovers from the Bourne shell. Like several other "extra" bash features, they exist to ensure upward compatibility; otherwise, their use is not encouraged.
Table 3.1 lists the options that are useful to general UNIX users. All of them are off by default except as noted.
Table 3.1: Basic Shell Options
Option Description
emacs
Enter emacs editing mode (on by default)
ignoreeof
Don't allow use of a single CTRL-D to log off; use the exit command to log off immediately. This has the same effect as setting the shell variable IGNOREEOF=10.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Shell Variables
There are several characteristics of your environment that you may want to customize but that cannot be expressed as an on/off choice. Characteristics of this type are specified in shell variables. Shell variables can specify everything from your prompt string to how often the shell checks for new mail.
Like an alias, a shell variable is a name that has a value associated with it. bash keeps track of several built-in shell variables; shell programmers can add their own. By convention, built-in variables should have names in all capital letters. bash does, however, have two exceptions. The syntax for defining variables is somewhat similar to the syntax for aliases:
            varname=value
         
There must be no space on either side of the equal sign, and if the value is more than one word, it must be surrounded by quotes. To use the value of a variable in a command, precede its name by a dollar sign ($).
You can delete a variable with the command unset varname. Normally this isn't useful, since all variables that don't exist are assumed to be null, i.e., equal to the empty string "". But if you use the option nounset, which causes the shell to indicate an error when it encounters an undefined variable, then you may be interested in unset.
The easiest way to check a variable's value is to use the echo built-in command. All echo does is print its arguments, but not until the shell has evaluated them. This includes—among other things that will be discussed later—taking the values of variables and expanding filename wildcards. So, if the variable wonderland has the value alice, typing:
$ echo "$wonderland"
         
will cause the shell to simply print alice. If the variable is undefined, the shell will print a blank line. A more verbose way to do this is:
$ echo "The value of \$
            varname
             is \"$
            varname
            \"."
         
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Customization and Subprocesses
Some of the variables discussed above are used by commands you may run—as opposed to the shell itself—so that they can determine certain aspects of your environment. The majority, however, are not even known outside the shell.
This dichotomy begs an important question: which shell "things" are known outside the shell, and which are only internal? This question is at the heart of many misunderstandings about the shell and shell programming. Before we answer, we'll ask it again in a more precise way: which shell "things" are known to subprocesses? Remember that whenever you enter a command,