1.8. Basic Shell Tools

1.8.1. Common Unix Shells

There are many different shells available for Unix systems. This might sound daunting if you're new to Unix, but fortunately, like most Unix tools, all the common shells adhere to certain standards.

All of the common shells are derived from one of two early shells:

  • Bourne shell (sh) is the de facto basic shell on all Unix systems, and is derived from the original Unix shell developed at AT&T.
  • C shell (csh) offers mostly the same features as Bourne shell, but the two differ in the syntax of their scripting languages, which are discussed in Chapter 2, Unix Shell Scripting. The C shell syntax is designed to be more intuitive and similar to the C language.

Most Unix commands are exactly the same regardless of which shell you are using. Differences will only become apparent when using more advanced command features or writing shell scripts, both of which we will cover later.

Common shells derived from Bourne shell include the following:

  • Almquist shell (ash), used as the Bourne shell on many BSD systems.
  • Korn shell (ksh), an extended Bourne shell with many added features for user-friendliness.
  • Bourne again shell (bash) another extended Bourne shell from the GNU project with many added features for user-friendliness. Used as the Bourne shell on many Linux systems.
  • Debian Almquist shell (dash), a reincarnation of ash which is used as the Bourne shell on Debian based Linux systems.

Common shells derived from C shell include the following:

  • T shell (tcsh), and extended C shell with many added features for user-friendliness.
  • Hamilton C shell, an extended C shell used primarily on Microsoft Windows.

Unix systems differ in which shells are included in the base installation, but most shells can be easily added to any Unix system using the system's package manager.

1.8.2. Command History

Most shells remember a configurable number of recent commands. This command history is saved to disk, so that you can still recall this session's commands next time you log in.

The exact mechanisms for recalling those commands varies from shell to shell, but some of the features common to all shells are described below.

Most modern shells support scrolling through recent commands by using the up-arrow and down-arrow keys. Among the popular shells, only very early shells like Bourne shell (sh) and C shell (csh) lack this ability.

Note

This feature may not work if your TERM variable is not set properly, since the arrow keys send magic sequences that may differ among terminal types.

The history command lists the commands that the shell currently has in memory.

shell-prompt: history
	    

A command consisting of an exclamation point (!) followed by any character string causes the shell to search for the most recently executed command that began with that string. This is particularly useful when you want to repeat a complicated command.

shell-prompt: find Programs -name '*.o' -exec rm -i '{}' \;
shell-prompt: !find
	    

An exclamation point followed by a number runs the command with that history index:

shell-prompt: history
   385  13;42   more output.txt
   386  13:54   ls
   387  13:54   cat /etc/hosts
shell-prompt: !386
ls
Avi-admin/            Materials-Studio/     iperf-bsd
Backup@               New-cluster/          notes
Books/                Peregrine-admin/      octave-workspace
	    

Tantalizing sneak preview: We can check the history for a particular pattern such as "find" as follows:

shell-prompt: history | grep find
	    

More on the "| find" in Section 1.18.1, “Redirection and Pipes”.

1.8.3. Auto-completion

In most Unix shells, you need only type enough of a command or argument filename to uniquely identify it. At that point, pressing the TAB key will automatically fill in the rest for you. Try the following:

shell-prompt: touch sample.txt
shell-prompt: cat sam<Press the TAB key now>
	    

If there are other files in your directory that begin with "sam", you may need to type a few additional characters before the TAB, like 'p' and 'l' before auto-completion will work.

1.8.4. Command-line Editing

Modern shells allow extensive editing of the command currently being entered. The key bindings for different editing features depend on the shell you are using and the current settings. Some shells offer a selection of different key bindings that correspond to Unix editors such as vi or Emacs.

See the documentation for your shell for full details. Below are some example default key bindings for shells such as bash and tcsh.

Table 1.3. Default Key Bindings in some Shells

KeyAction
Left arrowMove left
Right arrowMove right
Ctrl+aBeginning of line
Ctrl+eEnd of line
Backspace or Ctrl+hDelete left
Ctrl+dDelete current

1.8.5. Globbing (File Specifications)

There is often a need to specify a large number of files as command line arguments. Typing all of them would be tedious, so Unix shells provide a mechanism called globbing that allows short, simple patterns to match many file names.

These patterns are build from literal text and/or the special symbols called wild cards in Table 1.4, “Globbing Symbols”.

Table 1.4. Globbing Symbols

SymbolMatches
*Any sequence of characters (including none) except a '.' in the first character of the filename.
?Any single character, except a '.' in the first character of the filename.
[string]Any character in string
[c1-c2]Any character from c1 to c2, inclusive
{thing1,thing2}Thing1 or thing2

Normally, the shell handles these special characters, expanding globbing patterns to a list of matching file names before the command is executed.

If you want an argument containing special globbing characters to be sent to a command in its raw form, it must be enclosed in quotes, or each special character must be escaped (preceded by a backslash, \).

Certain commands, such as find need to receive the pattern as an argument and attempt to do the matching themselves rather than have it done for them by the shell. Therefore, patterns to be used by the find command must be enclosed in quotes.

The exemption for a leading '.' prevents accidental matching of hidden files.

shell-prompt: ls *.txt     # Lists all files ending in ".txt"
shell-prompt: ls "*.txt"   # Fails, unless there is a file called '*.txt'
shell-prompt: ls '*.txt'   # Fails, unless there is a file called '*.txt'
shell-prompt: ls .*.txt    # Lists hidden files ending in ".txt"
shell-prompt: ls [A-Za-z]* # Lists all files and directories
			   # whose name begins with a letter
shell-prompt: find . -name *.txt    # Fails
shell-prompt: find . -name '*.txt'  # List .txt files in all subdirectories
shell-prompt: ls *.{c,c++,f90}
	    

1.8.6. Self-test

  1. Which shells support modern interactive features such as scrolling through previous commands and command-line editing?
  2. Show the simplest command to accomplish each of the following:
    1. Show a list of recently executed commands.
    2. Re-execute the most recent command that began with "ls".
  3. Show the simplest command to accomplish each of the following:
    1. Move all the files whose names end with ".c" from the current directory to the directory ./Prog1.
    2. Remove all the files whose names end with ".o".
    3. List the contents of all files/directories in the current working directory whose names begin with a '.' followed by a capital letter or lower case letter, and end with a digit.