which Command in Linux: Find Executable Locations

You type python3 and get a version you did not expect, or a script fails because a binary is not where you assumed it was. The which command helps you investigate by searching the directories listed in the PATH environment variable and printing the full path of the first matching external executable.
This guide explains how to use which, how its two common implementations differ, and how it compares to type, whereis, and command -v.
Syntax
The syntax for the which command is:
which [OPTIONS] COMMAND...COMMAND- the name of one or more commands to locate.
Locate a Command
To find the full path of a command, pass its name as an argument. For example, to locate the ping command:
which ping/usr/bin/pingwhich searches the directories in PATH from left to right and prints the path of the first match it finds.
You can pass multiple command names at once:
which netcat uptime/usr/bin/netcat
/usr/bin/uptimewhich prints one result per command, in the same order they were given.
Print All Matches
When the same command name exists in more than one directory listed in PATH, which prints only the first match by default. To see all matches, use the -a option:
which -a python3/usr/local/bin/python3
/usr/bin/python3The results are printed in PATH order, so the first line is the external executable selected during a normal PATH search. Here /usr/local/bin/python3 comes first because /usr/local/bin appears earlier in PATH than /usr/bin.
This is useful when multiple versions of a command are installed. Usually one of the entries is a symlink to the other, but in some cases they are separate binaries.
What is PATH
PATH is an environment variable
that tells the shell which directories to search for executables. It is a colon-separated list of absolute directory paths.
To view your current PATH:
echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binThe shell searches these directories in order from left to right. The first match wins, which is the same order which uses. To add a directory to PATH, see the PATH guide
.
which Implementations and Options
Linux distributions do not all ship the same which. Two implementations are common, and they accept different options.
On Debian, Ubuntu, and their derivatives, /usr/bin/which is a symlink managed by update-alternatives that points to which.debianutils. This version is a small POSIX shell script, and it supports two options:
-a- print all matching pathnames instead of only the first.-s- print nothing and report the result through the exit status only.
Fedora, RHEL, and their derivatives ship GNU which instead, which is a separate program with a much larger option set:
--all,-a- print all matches inPATH.--read-alias,-i- read aliases from standard input and report them.--skip-alias- ignore aliases even when reading them is enabled.--read-functions- read shell functions from standard input and report them.--skip-dot- skip directories inPATHthat start with a dot.--skip-tilde- skip directories inPATHthat start with a tilde and executables located under the home directory.--show-dot- print./rather than expanding the current directory.--show-tilde- print a tilde rather than the full home directory path. This option is ignored whenwhichruns as root.--tty-only- stop processing options to its right when standard output is not a terminal.
If an option such as -i fails with an invalid option error, you are running the debianutils version. To install the GNU implementation on Debian and Ubuntu, you would type the following:
sudo apt install gnu-whichThe package installs the binary as which.gnu, so it does not replace the default which.
Exit Status and Scripting
which also reports its result through an exit status, but the exact values depend on the implementation. The debianutils version uses these values:
0- every command given was found and is executable.1- one or more commands were not found or are not executable.2- an invalid option was given.
GNU which returns 0 when it finds every command. Otherwise, it returns the number of command arguments it could not find. As a result, a nonzero status indicates failure with both implementations, but status 2 does not have the same meaning on both.
When you only care about whether a command exists, the debianutils version accepts -s to suppress the output:
which -s docker && echo "Docker is installed"Docker is installedNothing is printed by which itself. The message comes from echo, which runs only because which exited with status 0.
GNU which has no -s option. If you know that either the debianutils or GNU implementation is installed, redirect the output for the same one-command test:
which docker >/dev/null 2>&1 && echo "Docker is installed"Because the two implementations differ, most scripts use command -v instead. It is defined by POSIX, built into every POSIX shell, and behaves the same regardless of which package the distribution installed:
#!/bin/bash
if command -v docker >/dev/null 2>&1; then
echo "Docker is installed"
else
echo "Docker is not installed" >&2
exit 1
fiUse command -v in any script you expect to run on more than one distribution, and keep which for interactive use.
which vs. type, whereis, and command -v
Several commands serve a similar purpose. Here is how they differ:
which- searchesPATHand prints the path of the executable. Does not find shell builtins, and only finds aliases on systems that configure it to.type- a shell builtin that identifies how a name is interpreted: as a shell builtin, alias, function, or external command. Usetypewhen you want to know what the shell will actually run.whereis- locates the binary, source, and man page for a command. See thewhereisguide .command -v- POSIX-compliant alternative towhich. Works in scripts and finds both builtins and external commands.
For shell scripts, prefer command -v over which because it is portable and handles builtins correctly.
Quick Reference
For a printable quick reference, see the Linux commands cheatsheet .
| Task | Command |
|---|---|
| Locate a command | which command |
| Locate multiple commands | which cmd1 cmd2 |
| Show all matches in PATH | which -a command |
| Test silently (debianutils) | which -s command |
| Test silently (portable) | command -v command >/dev/null 2>&1 |
| View current PATH | echo $PATH |
| Portable alternative (scripts) | command -v command |
| Identify builtins and aliases | type command |
| Find binary, source, and man page | whereis command |
| Exit status (debianutils) | 0 all found, 1 not found, 2 bad option |
| Exit status (GNU which) | 0 all found, otherwise the number not found |
Troubleshooting
which returns no output
The command is either not installed, not in any PATH directory, or is a shell builtin or alias. Run type command to check. Builtins like cd and read are built into the shell and have no executable path for which to find.
Wrong version of a command is being used
Run which -a command to see all matches in PATH. The first result is the external executable selected during a normal PATH search. Reorder your PATH directories or use the full path to run a specific version.
which: no command in PATH
The command is not installed or its directory is not in PATH. Verify with echo $PATH and see the PATH guide
to add a directory.
which: command not found inside a container
Minimal and slim container images often strip it out. On Debian and Ubuntu images, install it with apt install debianutils. The better fix in a container build is to replace the call with command -v, which is available in POSIX shells.
which: invalid option
You passed a GNU which option to the debianutils version, which accepts only -a and -s. Check the exit status: it returns 2 for an unrecognized option.
FAQ
What is the difference between which and type?which searches PATH for an external executable file. type
is a shell builtin that tells you how a name is resolved, so it can identify aliases, functions, shell builtins, and external commands. For example, which cd returns nothing because cd is a builtin, but type cd correctly reports that.
Can which find shell aliases?
That depends on the implementation and shell configuration. The debianutils version on Debian and Ubuntu searches PATH only, so it never reports aliases. Fedora ships GNU which with /etc/profile.d/which2.sh, which defines an alias that passes shell aliases and functions to which --read-alias --read-functions. RHEL behavior varies by release. For a consistent answer, use type or alias.
Why does which python point to the wrong version?
During a normal PATH search, the first match wins. Run which -a python to see all installed versions and their paths, then adjust your PATH or use a version manager.
Is which available on all Linux systems?
It is present on virtually all Linux distributions, but as shown above the implementation and its options differ. Minimal container images sometimes omit it entirely. For portable scripts, use command -v instead.
What does it mean when which returns two paths for the same command?
Run which -a command to see all matches. One is often a symlink to the other. Use ls -l on both paths to check.
Conclusion
The which command locates external executables by searching the directories in PATH. Use -a to see all matches when multiple versions are installed, and check the implementation-specific exit status when you need a yes or no answer.
For shell scripts, prefer command -v for portability. To identify builtins and aliases, use type
. To learn how command resolution depends on your environment, see how to add a directory to PATH
.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page