Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I think most are familiar with the which command, and I use it frequently. I just ran into a situation where I'm curious not just which command is first in my path, but how many and where all the commands in all my paths are. I tried the which man page (typing man which made me laugh), but didn't see anything.

share|improve this question
On my system, it's the first thing listed on the man page: which --all. – Shawn J. Goff Mar 19 '11 at 23:43
On mine (linux) it's only which -a. – user unknown Mar 20 '11 at 8:59
up vote 14 down vote accepted

On some systems, which -a shows all matches. If your shell is bash or zsh¹, you can use type instead: type foo shows the first match and type -a foo shows all matches. The three commands type, which and whence do mostly the same thing; they differ between shells and operating systems in availability, options, and what exactly they report. type is always available and shows all possible command-like names (aliases, keywords, shell built-ins, functions, and external commands).

The only fully portable way to display all matches is to parse $PATH yourself. Here's a shell script that does this. If you make it a shell function, make sure to enclose the function body in parentheses (so that the change to IFS and set -f don't escape the function), and change exit to return.

set -f       # disable globbing
IFS=:        # break words at : only
for d in $PATH; do
  if [ -f "$d/$x" ] && [ -x "$d/$x" ]; then
    printf '%s\n' "$d/$x"
exit $not_found

¹ Or ksh 93, according to the documentation, though ksh 93s+ 2008-01-31 only prints the first match when I try.

share|improve this answer
That sh code doesn't work properly if there are empty components in $PATH. Also note that $IFS is a field delimiter (in POSIX shells at least) while in $PATH, colon is used as a field separator. See the which script found on Debian for a correct implementation. – Stéphane Chazelas Nov 25 '13 at 15:28
the type builtin in ksh93u+ 2012-08-01 seems to work properly. – Stéphane Chazelas Nov 25 '13 at 15:29

The --all or -a flag will show you all matches in your path, and aliases (at least on Fedora, Ubuntu and CentOS):

which -a which

On AIX and Solaris, this will get you close:

echo "$PATH" | sed -e 's/:/ /g' | \
while read -r p; do find "$p" -type f -name "which"; done
share|improve this answer
You need double quotes around parameter substitutions, otherwise the script won't work if $PATH contains whitespace or shell globbing characters. read -r is necessary to cope with backslashes. This is not a good method because find will take a long time and may return spurious matches if a directory in $PATH contains subdirectories. Fortunately, find is not useful here; see my answer. – Gilles Mar 20 '11 at 0:30
I knew find felt wrong since it would certainly be slow in nested directories. Globbing and spaces in $PATH? eww. But you're right (though you were nice enough not to say as much): my one liner was poorly written. – Eli Heady Mar 20 '11 at 1:25

ksh and zsh have "whence" as a shell built-in. whence -a does what you want under zsh:

 7:27AM 7 % whence -a cat

I have to clean up PATH in zsh, I have lots of duplicates in it. whence -a works differently under ksh:

$ whence -a cat
cat is a tracked alias for /usr/bin/cat

I have to say, that seems like a potentially useful behavior, too.

share|improve this answer

If you don't have a which supporting -a, or whence available, roll your own:

#!/bin/sh -f

for PART in $PATH
  if test -x "$PART/$1"
    echo $PART/$1
share|improve this answer
You're missing set -f to turn off globbing on the unprotected $PATH. test -f isn't sufficient since only executable files are wanted here; you need test -x. Hmm, I realize I forgot the regular file test in my script. – Gilles Mar 21 '11 at 21:03
@Gilles: edited according to your tips. I'm all for correctness, but I find whence README.txt as unlikely as whence "file* wi?h we!rd name". Just trying to show how easy it is to traverse $PATH. – MattBianco Mar 22 '11 at 8:58

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.