Super User is a question and answer site for computer enthusiasts and power users. 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

For example, if passed ls as input it should tell me that /bin/ls will run if run ls on the command-line.

share|improve this question

migrated from stackoverflow.com Oct 29 '11 at 16:16

This question came from our site for professional and enthusiast programmers.

up vote 18 down vote accepted

The command to use varies from shell to shell.

Only a shell built-in will tell one correctly what the shell will do for a given command name, since only built-ins can fully know about aliases, shell functions, other built-ins, and so forth. Remember: Not all commands correspond to executable files in the first place.

  • For the Bourne Again shell, bash, the built-in is the type command:

    $ type '['
    [ is a shell builtin
    
  • For the Fish shell, fish, The type builtin works similarly to bash. To get just the path to an executable, use command -v:

    $ type cat
    cat is /bin/cat
    $ command -v cat
    /bin/cat
    
  • For the Korn Shell, ksh, the built-in is the whence command — with type initially set up as an ordinary alias for whence -v and the command built-in with the -v option equivalent to whence:

    $ whence -v ls
    ls is a tracked alias for /bin/ls
    
  • For the Z Shell, zsh, the built-in is the whence command, with the command built-in with the -v option equivalent to whence and the built-ins type, which, and where equivalent to whence with the options -v, -c, and -ca respectively.

    $ whence ls
    /bin/ls
    
  • For the T C Shell, tcsh, the built-in is the which command — not to be confused with any external command by that name:

    > which ls
    ls: aliased to ls-F
    > which \ls
    /bin/ls
    
share|improve this answer
    
Note that under ksh, "type" is a default alias for "whence -v" so can be used just like with traditional bourne shell and bash. – jlliagre Oct 30 '11 at 10:19
    
type is also builtin to zsh? – Hongxu Chen Nov 24 '14 at 9:15
    
RHEL6's which RPM (e.g., which-2.19-6.el6.x86_64) puts a startup file in /etc/profile.d/which2.sh. This is read by non-csh shells, including zsh. It aliases which to itself. So for zsh users in particular it overrides breaks the builtin which. – Dan Pritts Dec 9 '14 at 3:51

You can use which for this:

aix@aix:~$ which ls
/bin/ls

It works by searching the PATH for executable files matching the names of the arguments. Note that is does not work with shell aliases:

aix@aix:~$ alias listdir=/bin/ls
aix@aix:~$ listdir /
bin    dev   initrd.img      lib32   media  proc  selinux  tmp  vmlinuz
...
aix@aix:~$ which listdir
aix@aix:~$

type, however, does work:

aix@aix:~$ type listdir
listdir is aliased to `/bin/ls'
share|improve this answer
    
Thanks, this is exactly what I want. – hugomg Oct 29 '11 at 15:43
3  
Be careful: if ls is a function or is aliased, you want 'type ls' rather than 'which ls' – William Pursell Oct 29 '11 at 15:45
1  
which is not necessarily enough on its own. It only returns the first found name in $PATH ... That name may be a symbolic link, and not the actual end-of-chain executable. – Peter.O Oct 29 '11 at 23:03

which does not (necessarily) return the executable file. It returns the first matching file name it finds in the $PATH (or multiple like named files when using which -a)... The actual executable may be multiple links away.

  • which locate
    /usr/bin/locate
    `
  • file $(which locate)
    /usr/bin/locate: symbolic link to /etc/alternatives/locate'

The command which finds the actual executable is readlink -e,
(in conjunction with which)

  • readlink -e $(which locate)
    /usr/bin/mlocate

To see all the intermediate links:

f="$(which locate)"             # find name in $PATH
printf "# %s\n" "$f"
while f="$(readlink "$f")" ;do  # follow links to executable
    printf "# %s\n" "$f"
done

# /usr/bin/locate
# /etc/alternatives/locate
# /usr/bin/mlocate
share|improve this answer

You can try:

whereis ls

It gives me:

ls: /bin/ls /usr/share/man/man1/ls.1.gz
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .