Build Your Skills: BASH for beginners

Learn the basic features of using the BASH shell, the most popular command-line interpreter for Linux.

Shells—the heart of your Linux operating system—are command-language interpreters that tell Linux what to do. They also serve as an interface to all the utilities and applications on your system.
This article appears courtesy of TechRepublic's TechProGuild, the subscription Web resource for IT administration and support professionals. Among other great benefits, TechProGuild offers in-depth technical articles, e-books, and weekly chats moderated by industry experts on hot topics such as the latest OS developments and career advancement. For helpful network administration tips and more, sign up now for a FREE 30-day trial of our TechProGuild service.
BASH is perhaps one of the easiest-to-use and most popular Linux shells. Although a number of other shells are available for Linux, BASH is an excellent place to start for people who are new to Linux. The most common shells on Linux and UNIX systems are the Bourne Shell (sh), the C Shell (csh), and the Korn Shell (ksh). BASH is an extension of the Bourne Shell, and it stands for Bourne Again Shell.

The benefits of BASH over the original Bourne Shell are many, but the biggest relates to how BASH handles user input. As I’ll show you in this Daily Drill Down, BASH provides several features that make entering commands a lot easier than with the Bourne Shell. Due to this ease of use, BASH is often favored over sh. However, BASH is completely backward-compatible with sh. Longtime users of sh will be familiar with how BASH works and can benefit from the many extra features.

Command-line completion
One of the nicest features of BASH is its command-line completion feature. If you want to change to a directory called games, you normally type cd games. With BASH, you simply type cd g; BASH knows which directory you want, and it will change to the games directory automatically. However, let’s suppose that you have a directory called games and another called graphics. In that case, BASH won’t know which directory you want; you have to use the command cd ga for BASH to know which directory you mean.

You can test BASH in this way, too. BASH can complete and display the command for you if you press the [Tab] key. For example, typing cd ga and pressing [Tab] displays cd games on the command line. In order for BASH to run the command, you must press [Enter]. Doing so verifies that the command with which BASH comes up is really the command you intended to run. If BASH can't complete your command, it will beep at you, alerting you to the fact that it needs more information to complete the command. BASH will provide a list of possibilities that match the letters you’ve typed, and you can make the appropriate selection.

I can't think of a better use for this feature than for viewing program documentation. More often than not, documentation is placed into the /usr/doc directory tree—in a subdirectory with the same name as the program and version. Say that you want to look at the documentation for xmms, the X MultiMedia System. Without knowing the version number, you can type cd /usr/doc/xmms. BASH will change to the /usr/doc/xmms-0.9.1 directory, where the documentation for the currently installed version of xmms resides.

Command history
Another nice feature of BASH is the command history. BASH will keep track of a certain number of previously issued commands in the ~/.bash_history file (which is customizable via the HISTFILE bash variable). The number of commands in the history is likewise customizable via the HISTSIZE variable.

When you first enter the shell, the history list is initialized by the defined history file (~/.bash_history). The history list is kept in memory until you exit the shell, at which point the list is written to the history file, overwriting its current contents. Even when you log in initially, you have a history of what you did during your last login session.

You can access the commands that are stored in the history file by using the up and down arrow keys to move to a previously issued command, similar to the DOSKEY utility. Once you’ve selected a command, you can edit it to suit your needs by inserting or deleting characters. (Use the right and left arrows to move within the command.) BASH provides the means to edit commands on the command line, similar to commands used in the emacs and vi editors. Instead of typing a long command, you can recall a previous command that’s similar to the one you want to run now, and you can modify it.

Another method of accessing the command history is to use the history and fc commands. The history command, by default, lists the lines that are contained in the history file, and it can be limited to x number of lines. For example, issuing the command history 10 displays the last 10 lines in the history file. You also can use the history command to modify the contents of the history file. In this form, history has the following command-line syntax:
history [-r|w|a|n] [filename]

The command-line options for history are quite simple. The -r option tells history to read the contents of the history file and use them as the current history list. The -w option tells history to write the current history list to the history file and overwrite its current contents. The -a option tells history to append the current history list to the history file, and the -n option causes the lines that are in the history file to be read into the current history list. Finally, the [filename] command option can be used to specify a filename other than the one that’s used by the HISTFILE variable.

You can use the fc (fix command) command to edit the command history directly. The fc command has the following command-line syntax:
fc [-e editor] [-n] [-l] [-r] [first] [last]

All of the options within braces are optional. The [first] and [last] options are used to take a range of commands out of the history list; you can specify the number of the command or a string to match. The -n option is used to suppress command numbers when the history command lists the command history. The -l option lists the matched commands to the screen. Finally, the -r option lists the commands in reverse order. In all cases, except when you use the -l option, the results of the fc command are loaded into the text editor.

The text editor that fc uses can be specified on the command line with the -e option. However, if that option is not specified, fc will take the editor name from the FCEDIT variable. If that variable doesn't exist, fc will use the EDITOR variable. Finally, if that variable doesn't exist, fc will use vi by default.

Like any other shell on any operating system, BASH also supports wildcards. The supported wildcard types include the following:
  • * matches any character or any number of characters
  • ? matches any single character
  • [...] matches any single character contained within the brackets
  • {...} matches a specified range of characters contained within the curly brackets

The * wildcard works like you’d expect because it’s universally used by nearly every shell for every operating system in existence. The ? wildcard is similar to the * wildcard, except that it matches only a single character. The [...] wildcard allows you to specify which characters (or range of characters) you want matched. The {...} wildcard lets you specify a more detailed range of characters to match. You can match single characters or multiple characters if you separate them with commas. For example, the wildcard file{ab,123,s,test}23 would match fileab23, file12323, files23, and filetest23.

Suppose that you have the files test1.doc, test2.doc, test3.doc, and my.doc in the directory. The following illustrates how the various wildcards work:
  • ls *.doc displays test1.doc, test2.doc, test3.doc, and my.doc.
  • ls test?.doc displays test1.doc, test2.doc, and test3.doc.
  • ls test[12].doc displays test1.doc and test2.doc.
  • ls test[1-3].doc displays test1.doc, test2.doc, and test3.doc.
  • ls test{1,3}.doc displays test1.doc and test3.doc.

Those of you who are familiar with JPSoft's shell replacements for DOS, OS/2, and Windows (4DOS, 4OS2, and 4NT, respectively) will appreciate the aliases feature in BASH. Aliases are designed to save you some typing and make life simpler.

For example, suppose that you like different views with the ls command but don't always want to specify the options on the command line (or perhaps you can't remember them). You may want to do something like this:
alias lsa='ls -alF'

This command gives you a long directory listing that shows all filenames and adds a slash to directory names for easier viewing. If you're a newcomer to Linux from a DOS-like operating system (such as MS-DOS, Windows, or OS/2), you may want to make things easier for yourself by defining a number of aliases like this:
  • alias dir='ls'
  • alias copy='cp'
  • alias rename='mv'
  • alias md='mkdir'
  • alias rd='rmdir'

To turn off an alias, just type unalias [alias]. For example, to turn off the dir alias, type unalias dir. To load aliases each time you enter the shell, enter the commands in the ~/.bash_profile or ~/.profile file, depending on which distribution you use. The ~/.bash_profile file contains a number of commands that set the environment for the BASH shell, not just aliases, and it’s initialized every time that you start a new shell.

Pipes (or pipelines) are a way to string a number of commands together. The output from the first command is "piped" into the second command as input, the output from the second command is "piped" into the third command as input, and so on. The output from the last command is printed to the screen (or redirected to a file). In order to pipe commands, you must use the pipe (vertical bar or "|" character). It tells BASH where one command ends and the next begins. There’s no limit to the number of pipes you can use.

Suppose that you’re searching for the names of installed RPM packages. You’re looking for all the packages that have to do with MySQL, and you need to know all the names of the packages. You could accomplish this task with the following command:
rpm -qa | grep MySQL

This command tells RPM to query the local database. The command’s output (the list of all the installed RPM packages) is piped into the grep command, which searches for a string of "MySQL." (Case is important, of course.) The output of this command might be

There are literally hundreds of uses for pipes, ranging from simple tasks (like the one above) to extremely convoluted tasks.

BASH, like every other shell, supports redirection for commands. You can redirect the output from a command to a file or device other than the local console. Likewise, you can use a file or device to provide input to a command. There are a number of uses for redirection—more for output redirection than for input redirection—but you’ll encounter many situations where either method can be used.

To redirect the output from a command to a new file (or overwrite an existing file), use the > symbol. For instance, if you want the output from the df program (which shows you how much free space you have on each mounted device), you might use
df > ~/df.txt

This command will redirect the output from the df command to the file df.txt, which is located in your home directory. To redirect the output from a command to a new file (or append to the end of an existing file), use the > symbol twice (that is, >>).

The redirection point doesn’t necessarily have to be a file. You can redirect the output of a program to another virtual console, a printer, or any other device. Simply use the device name, as opposed to a filename. For example, to redirect the output of df to the second virtual console, type
df > /dev/tty2

You may find a use for input redirection at some point. Input redirection is not used nearly as much as output redirection, but it’s definitely helpful. Let's say that you have the file article.txt and you want to obtain the number of words in the file. You can use something as simple as wc article.txt, or you could use input redirection like this:
wc < article.txt

Some programs request input from the console by default and don’t let you specify a filename on the command line. Fortunately, wc isn’t one of these programs. Input redirection is helpful when you’re dealing with programs of this nature.

Suspending processes
Another feature of BASH is its ability to suspend currently running processes, otherwise known as Job Control. With Process Suspension, you can suspend a command that you executed on the command line, and you can resume it later.

Pressing [Ctrl][Z] suspends the currently running process. You can use two commands, bg and fg, to resume the process in the background or the foreground, as required.

More often than not, these commands become important when users start a program in the foreground but meant to start it in the background. When a command is started in the foreground, it locks the console until the process is complete. Usually, programs execute quite quickly, and it isn't a problem. However, some programs, like system daemons, are meant to be started in the background and remain there. Or perhaps you started a process that will take more than a few minutes to finish, and you want the console back. A few options are open to you at that point. You can open a new xterm (in X) or switch to a free virtual console, or you can suspend the process and restart it in the background. To suspend and restart a process in the background, issue

at the console. The first command suspends the currently running program, and the second restarts it in the background.

Vincent Danen, a native Canadian in Edmonton, Alberta, has been computing since the age of 10, and he has been using Linux for nearly two years. Vincent is a firm believer in the philosophy behind the Linux "revolution,” and he attempts to contribute to the Linux cause in as many ways as possible—from his FreezerBurn Web site to building and submitting custom RPMs for the Linux Mandrake project.


Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years and is a veteran Mac user.