The which command is a real life saver. It has become increasingly important in the last few years. Many vendors (like Sun) are providing separate directories of BSD-compatible and System V-compatible commands. Which command you'll get depends on your environment variable. It's often essential to know which version you're using. For example:
tells me exactly which version of the sort program I'm using. (Under SunOS 4.1, this is the BSD-compatible version in /bin, not the System V version in /usr/5bin.)
You'll find that which comes in handy in lots of other situations. I find that I'm always using which inside of backquotes to get a precise path. For example, when I was writing these articles, I started wondering whether or not man, apropos, and whatis were really the same executable. It's a simple question, but one I had never bothered to think about. There's one good way to find out:
ls -li `which man` `which apropos` `which whatis`102352 -rwxr-xr-x 3 root 24576 Feb 8 1990 /usr/ucb/apropos 102352 -rwxr-xr-x 3 root 24576 Feb 8 1990 /usr/ucb/man 102352 -rwxr-xr-x 3 root 24576 Feb 8 1990 /usr/ucb/whatis
What does this tell us? First, the three commands have the same file size, which means that they're likely to be identical; furthermore, each file has three links, meaning that each file has three names. The -i option confirms it; all three files have the same. So, apropos, man, and whatis are just one executable file that has three hard links.
|which||A few System V implementations don't have a which command. The version of which on the CD-ROM is even better than the BSD which, anyway. By default, this new which works about the same as the BSD which. The new which has a big plus: it doesn't try to read your .cshrc file to see what aliases you've set there. Instead, you set it up with its -\i option to read your shell's current list of aliases. This lets the new which show aliases that you've typed at a prompt and haven't stored in .cshrc. The new which also works inthat have .|
|To make the new which read your current aliases, you need a trick. Here's the trick: make an alias or shell function that runs which, passing the definition (if any) of the alias or function you name.|
Let's look at the setup, then explain it. For the C shell, use the following line in your .cshrc file:
alias which alias !\$ /usr/local/bin/which -i !\*
(There's a similar shell function on the CD-ROM.) For this example, let's say you've also defined an alias for sort that looks like:
alias sort /usr/local/bin/quicksort
Okay. To run which, you type:
which sortsort /usr/local/bin/quicksort
How did that work? The C shell runs the alias you defined for which. In this example, that executes the following command:
alias sort | /usr/local/bin/which -i sort
The first part of that command,
alias sort, will pipe the definition of the sort alias to the
standard input of
/usr/local/bin/which -i sort.
When /usr/local/bin/which -i sort sees an alias definition on its
standard input, it outputs that definition.
What if you ask which to find a command that you haven't aliased?
The shell runs this command:
alias tr | /usr/local/bin/which -i tr
Because there's no alias for tr, the shell command
sends no output down the pipe.
/usr/local/bin/which -i tr doesn't read text on standard
input, it looks through your search path for the first command named tr.
Nice trick, isn't it? Maarten Litmaath, the program's author, is a clever guy.
That's not all the new which can do.
With the -a option, it shows any alias you name and also
searches your path for all commands with that name.
This is useful when you want to know all available versions of the command.
Let's end this article with an example from the manual page.
The first command shows all aliases (in this case, that's just the
alias for the new which).
Second, we run the new which to find which which we're running
:-); it shows the alias for which.
Third, the -a option shows all available whiches:
aliaswhich alias !$ | /usr/local/bin/which -i !* %
which whichwhich alias !$ | /usr/local/bin/which -i !* %
which -a whichwhich alias !$ | /usr/local/bin/which -i !* /usr/local/bin/which /usr/ucb/which %