UNIX Power Tools

UNIX Power ToolsSearch this book
Previous: 50.7 How UNIX Systems Remember Their Name Chapter 50
Help--Online Documentation, etc.
Next: 50.9 Reading a Permuted Index
 

50.8 Which Version Am I Using?

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 PATH (6.4) environment variable. It's often essential to know which version you're using. For example:

% which sort
/bin/sort

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 i-number (1.22). 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 in Bourne-like shells (1.8) that have shell functions (10.9).
csh_init
sh_init
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 sort
sort    /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?

% which tr
/bin/tr

The shell runs this command:

alias tr | /usr/local/bin/which -i tr

Because there's no alias for tr, the shell command alias tr sends no output down the pipe. When /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:

% alias
which   alias !$ | /usr/local/bin/which -i !*
% which which
which   alias !$ | /usr/local/bin/which -i !*
% which -a which
which   alias !$ | /usr/local/bin/which -i !*
/usr/local/bin/which
/usr/ucb/which
%

- ML, JP, MAL


Previous: 50.7 How UNIX Systems Remember Their Name UNIX Power ToolsNext: 50.9 Reading a Permuted Index
50.7 How UNIX Systems Remember Their Name Book Index50.9 Reading a Permuted Index

The UNIX CD Bookshelf NavigationThe UNIX CD BookshelfUNIX Power ToolsUNIX in a NutshellLearning the vi Editorsed & awkLearning the Korn ShellLearning the UNIX Operating System