[Chapter 10] 10.3 C Shell Aliases with Command-Line Arguments
Author: Jerry Peek, Tim O'Reilly & Mike Loukides
Date: 1998-08-04T21:35:46Z

#

| Chapter 10 Aliases |

## 10.3 C Shell Aliases with Command-Line Arguments

It's convenient for your aliases to use command-line arguments. For example, let's think about an alias named phone:

>     alias phone 'cat ~/phonelist | grep -i'

After you define that alias, you could type phone smith. The shell would find the phone alias and execute it with the argument (smith) at the end (10.2) this way:

>     cat ~/phonelist | grep -i smith

Using cat and a pipe that way is inefficient (13.2). It might be more sensible to have an alias that worked like this:

>     grep -i name ~/phonelist

How do we do this? The C shell's history (11.7) facility lets us use the notation `!$` to refer to the last word in the previous command; the notation `!*` refers to all the arguments of the previous command. Assuming that we only want to look up aliases one at a time, we can use `!$` and write our alias like this:

>     alias phone grep -i \!$ ~/phonelist

When we use the phone command, its final argument will be substituted into the alias. That is, when we type `phone bill`, the shell executes the command `grep -i bill ~/phonelist`.

In this example, we needed another kind of quoting. We had to put a backslash before the exclamation point to prevent the shell from replacing `!$` with the previous command's last argument. That is, we don't want the shell to expand `!$` when we define the alias - that's nonsense. We want the shell to insert the previous argument when we use the alias (in which case, the previous argument is just the argument for the alias itself - clear?).

But why couldn't we just use single quotes or double quotes (8.14)? This isn't the right place for a full explanation, but neither single quotes nor double quotes protect the exclamation point. The backslash does . (8.15) If you want to be convinced, experiment with some commands like:

>     % echo '!!'   Print your last command
>     % echo '\!!'   Print !!

The first echo command shows that the shell performs history substitution (i.e., replaces `!!` with your previous command) in spite of the single quotes. The second example shows that the backslash can prevent the shell from interpreting `!` as a special character.

Let's look at another alias. We want to pipe the output of ls -l into more (25.3). In this case, we would want all the arguments from the command line instead of merely the last argument (or the only argument). Here's the alias:

>     alias lm 'ls -l \!* | more'

This time, we needed both kinds of quoting: A backslash prevents the shell from interpreting the exclamation point immediately. Single quotes protect the pipe symbol and the asterisk (`*`). If you don't protect them both, and only protect the pipe (with a backslash), look what happens:

>     % alias lm ls -l \!*  more
>     alias: No match.

Because the backslash temporarily stops the special meaning of the `!`, the shell next tries to find filenames that match the wildcard (1.16) pattern `!*`. That fails (except in the unusual case when you have a file in the current directory whose name starts with a `!`).

> NOTE: Here's a good general rule for quoting aliases. Unless you're trying to do something special with an alias and you understand quoting well, put single quotes (`'`) around the whole definition and put a backslash before every exclamation point (`/!`).

Finally, if you want to pick one argument from the command line, use `/!:``n`, where `n` is the number of the argument. Here's one final alias. It uses cat (25.2) to add a header file to the file named in the first argument, then writes them both into the file named in the second argument:

    ~
    alias addhead 'cat ~/txt/header \!:1 > \!:2'

This alias has two arguments: the file to which you want to add a header and the output file. When you type:

>     % addhead foo bar

the C shell substitutes the filename `foo` for `/!:1`, and the filename `bar` for `/!:2`, executing the command:

>     cat ~/txt/header foo > bar

- ML, JP

10.2 Aliases for Common Commands |  | 10.4 Aliases in ksh and bash