Here's an (incomplete) list of shells available for Unix-like operating systems:
sh ash bash csh tcsh ksh zsh rc es sashbash, tcsh, zsh and ksh are probably the most popular these days. Here we look at bash, but (almost?) all the features covered here can be found in one form or another in the other popular shells.
alias h=historyBash only supports simple substitution in aliases; other shells' aliases can be considerably more complicated. However, the same effect can be achieved in bash by using shell functions. For example:
alias ls='/bin/ls -CF'
alias cp='/bin/cp -i'
alias mv='/bin/mv -i'
unalias rm
lm() { /bin/ls -Flag $* | /bin/more }... but shell programming is a large topic on its own.
Bash supports two different kinds of history. One comes from its use of the GNU `readline' library. This allows one to scroll up and down the history, searching, copying, modifying, etc. using emacs-like (or vi-like if you prefer) key bindings.
The other is similar to the history expansion provided by `csh' and
its derivatives. Some examples:
| !! | The previous command |
| !-5 | The fifth last command |
| !372 | Command number 372 |
| !foo | The last command starting with `foo' |
| !?bar? | The last command containing the string `bar' |
| ^foo^bar | The previous command, with `foo' replaced by `bar' |
| !^ | The first argument of the previous command |
| !$ | The last argument of the previous command |
| !* | All the arguments of the previous command |
| !?foo?:3:h:gs/bar/baz/ | Argument 3 of the last command containing the string `foo' with the trailing pathname component stripped off and all occurrences of `bar' replaced by `baz' |
The current history list can be displayed with the `history' command.
Bash tries to be smart about its completion. If the word being completed starts with `$', it tries completing it as a shell variable. If it starts with a `~', it tries completing it as a user name. If it starts with a `@', it tries completing it as a host name. When appropriate, it tries completing it as a command (including aliases and functions). When all of the above don't work, it tries filename completion. (Note that there are key bindings for doing all of the above specifically, including just printing the options rather than performing the completion.)
| * | All files (except those starting with `.') |
| foo*bar | All files starting with `foo' and ending with `bar' |
| ba? | All three-character files starting with `ba' |
| foo?*bar | All files starting with `foo' and ending with `bar' with at least one character between them |
| [A-Z]* | All files starting with a capital letter |
| *.[ch] | All files ending in `.c' or `.h' |
| *[^0-9] | All files which don't end in a number |
If the pattern matches at least one file, it is replaced by the matching file(s) (in sorted order). If there are no matches, the pattern is left as it is.
Related to the above is `brace expansion', though this does not match
against files (unless wildcards appear in the result). Examples:
| a{b,c,d}e | Expands to `abe ace ade' |
| /usr/{bin,lib,man} | Expands to `/usr/bin /usr/lib /usr/man' |
| /usr/{,local/}{bin,lib,man} | Expands to `/usr/bin /usr/lib /usr/man /usr/local/bin /usr/local/lib /usr/local/man' |
| foo > bar | Redirects the output of `foo' to the file `bar' |
| foo 2> bar | Redirects the error output of `foo' to the file `bar' |
| foo >> bar | Appends the output of `foo' to the file `bar', rather than clobbering it |
| foo < bar | Causes `foo' to read its input from the file `bar' |
| foo | snafu | Takes the output of `foo' and feeds ("pipes") it into `snafu' as input |
The `2' in `2>' above refers to a `file descriptor'. Standard
file descriptor numbers:
| 0 | Standard input |
| 1 | Standard output |
| 2 | Standard error |
You can also "copy" file descriptors:
| foo 2>&1 | Sends the error output to the same place as the standard output (useful for sending both to the same place) |
Redirections can be combined, but the order can be important:
| foo > bar 2> baz | Redirects the output of `foo' to the file `bar', and the error output to the file `baz' |
| foo > bar 2>&1 | Redirects the output of `foo' to the file `bar', and then redirects the error output to the same place |
| foo 2>&1 > bar | Redirects the error output to where the standard output (was) going, and then redirects the standard output (only) to `bar' |
| foo &> bar | Same as `foo > bar 2>&1' (short-cut) |
| foo 2>&1 | snafu | Pipes both the standard output and the error output of `foo' into the input of `snafu' (the pipe redirection is always done first, so when the error output is sent to the same place as the standard output, the standard output is already being sent to the pipe) |
| & ; ( ) < > $ ` ' " \ space tabThese have to be "quoted" if they are not intended to be interpreted by the shell. One way to do this is to precede the character by a backslash (\). Another way is to enclose all or part of a string within quotation marks. Note that the different quotation marks have different meanings.
| '...' | Everything within the string is kept verbatim |
| "..." | Most things kept verbatim: dollar ($) and backquotes (`) still special |
| `...` | Not to be confused with '...'! This executes the enclosed string as if it were a command and replaces it with the command's output |
Compare the following commands:
echo 'rm -rf *' ; sleep 5
echo `rm -rf *` ; sleep 5
| pwd | Print the current directory |
| pushd | "Push" the current directory onto the directory stack and change to another directory |
| popd | "Pop" the current directory off the directory stack |
| dirs | Print the directory stack |
| tee | Copy its input to a file as well as printing it on standard output |
| echo | Print its arguments on standard output |
If you're familiar with `info' or `emacs', you may also like to look at the info page (`info bash').
O'Reilly have a book on bash, `Learning the bash Shell' (2nd ed), but I've not seen it so can't really comment.
There are no doubt many net resources around. As an undergrad,
I found Zoltan Somogyi's lectures on shell programming quite useful.
He has some lecture notes available
(slide set #2), as well as some sample
shell scripts.