After you close your shell, the history list is stored in the .bash_history
file in your home directory. Up to 1,000 history commands are stored for you by default.
NOTE
Some people disable the history feature for the root user by setting the HISTFILE
shell variable to /dev/null
or simply leaving HISTSIZE
blank. This prevents information about the root user's activities from potentially being exploited. If you are an administrative user with root privileges, you may want to consider emptying your file upon exiting as well for the same reasons. Also, because shell history is stored permanently when the shell exits properly, you can prevent storing a shell's history by killing a shell. For example, to kill a shell with process ID 1234, type kill -9 1234 from any shell.
Connecting and Expanding Commands
A truly powerful feature of the shell is the capability to redirect the input and output of commands to and from other commands and files. To allow commands to be strung together, the shell uses metacharacters. A metacharacter is a typed character that has special meaning to the shell for connecting commands or requesting expansion.
Metacharacters include the pipe character (|
), ampersand (&
), semicolon (;
), right parenthesis ()
), left parenthesis ((
), less than sign (<
), and greater than sign (>
). The next sections describe how to use metacharacters on the command line to change how commands behave.
Piping between commands
The pipe (|
) metacharacter connects the output from one command to the input of another command. This lets you have one command work on some data and then have the next command deal with the results. Here is an example of a command line that includes pipes:
$ cat /etc/passwd | sort | less
This command lists the contents of the /etc/passwd
file and pipes the output to the sort
command. The sort
command takes the usernames that begin each line of the /etc/passwd
file, sorts them alphabetically, and pipes the output to the less
command (to page through the output).
Pipes are an excellent illustration of how UNIX, the predecessor of Linux, was created as an operating system made up of building blocks. A standard practice in UNIX was to connect utilities in different ways to get different jobs done. For example, before the days of graphical word processors, users created plain-text files that included macros to indicate formatting. To see how the document really appeared, they would use a command such as the following:
$ gunzip < /usr/share/man/man1/grep.1.gz | nroff -c -man | less
In this example, the contents of the grep
man page (grep.1.gz
) are directed to the gunzip
command to be unzipped. The output from gunzip
is piped to the nroff
command to format the man page using the manual macro (-man
). To display the output, it is piped to the less
command. Because the file being displayed is in plain text, you could have substituted any number of options to work with the text before displaying it. You could sort the contents, change or delete some of the content, or bring in text from other documents. The key is that, instead of all of those features being in one program, you get results from piping and redirecting input and output between multiple commands.
Sequential commands
Sometimes, you may want a sequence of commands to run, with one command completing before the next command begins. You can do this by typing several commands on the same command line and separating them with semicolons (;
):
$ date ; troff -me verylargedocument | lpr ; date
In this example, I was formatting a huge document and wanted to know how long it would take. The first command (date
) showed the date and time before the formatting started. The troff
command formatted the document and then piped the output to the printer. When the formatting was finished, the date and time were printed again (so I knew how long the troff
command took to complete).
Another useful command to add to the end of a long command line is mail
. You could add the following to the end of a command line:
; mail -s "Finished the long command" [email protected]
Then, for example, a mail message is sent to the user you choose after the command completes.
Background commands
Some commands can take a while to complete. Sometimes, you may not want to tie up your shell waiting for a command to finish. In those cases, you can have the commands run in the background by using the ampersand (&
).
Text formatting commands (such as nroff
and troff
, described earlier) are examples of commands that can be run in the background to format a large document. You also might want to create your own shell scripts that run in the background to check continuously for certain events to occur, such as the hard disk filling up or particular users logging in.
The following is an example of a command being run in the background:
$ troff -me verylargedocument | lpr &
Don't close the shell until the process is completed or that kills the process. Other ways to manage background and foreground processes are described in Chapter 6, “Managing Running Processes.”
Expanding commands
With command substitution, you can have the output of a command interpreted by the shell instead of by the command itself. In this way, you can have the standard output of a command become an argument for another command. The two forms of command substitution are $(command)
and `command`
(backticks, not single quotes).
The command in this case can include options, metacharacters, and arguments. The following is an example of using command substitution:
$ vi $(find /home | grep xyzzy)
In this example, the command substitution is done before the vi
command is run. First, the find
command starts at the /home
directory and prints out all of the files and directories below that point in the filesystem. The output is piped to the grep
command, which filters out all files except for those that include the string xyzzy
in the filename. Finally, the vi
command opens all filenames for editing (one at a time) that include xyzzy
. (If you run this and are not familiar with vi
, you can type :q! to exit the file.)
This particular example is useful if you want to edit a file for which you