PATH problems usually look simple until two copies of the same tool exist on one system. The which command in Linux shows the executable path your current $PATH resolves first, which makes it useful for checking interpreters, package installs, and script prerequisites before you run the wrong binary.
That narrow scope matters. which finds executable files, not aliases, shell functions, package owners, or manual pages. Use it for quick path checks, then switch to command -v, type, whereis, or your package manager when the question goes beyond executable lookup.
Understand the which Command
Your shell searches directories in $PATH from left to right when you type an external command name. The which command performs that executable-file lookup and prints the first matching path, or every matching path when you add -a.
This makes which useful for interactive checks such as confirming whether python3 points to a system interpreter or a locally installed copy in /usr/local/bin. It is less reliable as a full shell diagnostic because aliases, functions, built-ins, and Bash’s command hash table can affect what the shell actually runs.
which Command Syntax
The basic syntax takes one or more command names:
which command_name
For example, locate the executable path for ls:
which ls
A typical merged-/usr system returns:
/usr/bin/ls
which Command Quick Reference
| Task | Command Pattern | What It Does |
|---|---|---|
| Find the first executable path | which grep | Prints the first matching executable in $PATH. |
| Find several commands at once | which grep sed awk | Prints one path per command, in the order requested. |
| Show every executable match | which -a python3 | Lists all matching executable paths in $PATH order. |
| Check a shell builtin or alias | type echo | Shows how the shell interprets the command name. |
| Use a portable script check | command -v docker | Works in POSIX-style shells and handles built-ins better than which. |
Verify the which Command Is Available
Most full Linux installs already include which. Minimal containers and stripped-down images may omit it, so check availability with the shell’s built-in lookup first:
command -v which
A normal system returns the path to the executable:
/usr/bin/which
If the command is missing, install the package that provides it through your distribution’s normal package manager. Debian and Ubuntu provide the default implementation through debianutils, with gnu-which available as an alternate GNU implementation where that package is published. Fedora, RHEL-family distributions, openSUSE, Arch, Alpine, and Void commonly use a package named which; Gentoo uses sys-apps/which.
Do not remove a distribution’s baseline
whichprovider just to test examples. On Debian and Ubuntu,debianutilsis part of the base system, and removing baseline utilities can affect unrelated maintenance tasks.
Use Practical which Command Examples
Locate Common Utilities
Use which with a single command name when you need the executable path for an interactive check:
which grep
/usr/bin/grep
You can also query several command names in one call:
which grep sed awk
/usr/bin/grep /usr/bin/sed /usr/bin/awk
Each path appears on its own line. If text-processing is the next task, continue with grep command in Linux for filtering or sed command in Linux for stream editing.
Check Which Python Runs First
Language runtimes often have system, local, and virtual-environment copies. Check the first python3 path your current shell resolves:
which python3
/usr/bin/python3
Then ask for all matching executable paths:
which -a python3
/usr/bin/python3 /bin/python3
On many modern distributions, /bin and /usr/bin are part of a merged directory layout, so these two entries can point to the same underlying file. If /usr/local/bin/python3 appears before /usr/bin/python3, the local interpreter takes priority in that shell.
Check a Shell Location
Executable-path checks are also useful before writing a shebang line for a script:
which bash
/usr/bin/bash
A script that needs Bash-specific syntax can use this path in a shebang such as #!/usr/bin/bash. For scripts that should run on more Unix-like systems, #!/usr/bin/env bash is often more flexible because it searches the caller’s $PATH.
Check Script Prerequisites
For interactive checks, which docker answers whether an executable named docker appears in $PATH. In scripts, prefer command -v because it is shell-defined and avoids dependency on an external which binary:
if command -v docker >/dev/null 2>&1; then
printf 'Docker is available\n'
else
printf 'Docker is not in PATH\n'
fi
The redirection sends normal output and errors to /dev/null, so the conditional uses only the exit status. Use this pattern when the script only needs to decide whether the command name is available.
Compare the which Command with command -v, type, and whereis
which is one lookup tool, not the whole command-resolution model. The right alternative depends on whether you need executable paths, shell behavior, package ownership, or documentation paths.
| Tool | Searches | Best Use |
|---|---|---|
which | Executable files in $PATH | Quick interactive check for the path to an external command. |
command -v | Shell command resolution | Portable shell scripts and existence checks. |
type | Aliases, functions, built-ins, keywords, and files | Explaining what the current shell will actually run. |
whereis | Standard binary, source, and manual-page paths | Auditing installed files beyond $PATH. |
| Package manager | Installed package database or repository index | Finding which package owns or provides a command. |
Use which for the first executable path, type when aliases or built-ins might be involved, and command -v inside scripts. For broader binary, source, and manual-page lookups, use the whereis command in Linux.
Use type for Built-ins and Aliases
The echo command is a common example because Bash has a built-in echo even though an external binary also exists:
which echo
/usr/bin/echo
That output is real, but it does not mean Bash will run the external binary first. Ask the shell directly:
type echo
echo is a shell builtin
The same applies to commands such as cd, which exists only as a shell built-in in normal Bash sessions:
type cd
cd is a shell builtin
Use whereis for Documentation Paths
which stops at executable files in $PATH. When you also need manual pages or standard source paths, whereis gives a broader installed-file view:
whereis bash
bash: /usr/bin/bash /usr/share/man/man1/bash.1.gz
This is a different question from “which executable runs first.” Use whereis when documentation or standard installation paths matter.
Use Advanced which Command Checks
Check PATH Priority with which -a
The -a option is the safest way to spot duplicate command names before changing $PATH or troubleshooting a version mismatch:
which -a ls
/usr/bin/ls /bin/ls
The first path is the one selected by a normal path lookup. Duplicate entries can be harmless on merged-/usr systems, but a user-local path such as /home/alex/.local/bin/tool before /usr/bin/tool means the user-local copy wins.
Find Which Package Owns a Command
which does not know package ownership. It only prints executable paths. On Debian and Ubuntu, resolve symlinks first, then ask dpkg which installed package owns the file:
dpkg -S "$(readlink -f "$(command -v which)")"
Relevant output on a default Debian-family system includes:
debianutils: /usr/bin/which.debianutils
For Alpine package-provider searches, use the package manager’s cmd: provider prefix. For example, this searches Alpine repositories for packages that provide the git command:
apk search -v 'cmd:git'
Package-provider searches are package-manager features, not which features. Use them when the command is not installed yet or when you need the package name rather than the executable path.
Check which Implementation You Have
The which implementation changes which options are available. GNU which supports --version and extra alias/function-reading options, Debian’s debianutils implementation supports a smaller option set, and BusyBox which usually supports only -a.
Do not rely on which --version as a universal availability check. On a Debian-family system using the debianutils implementation, that option returns an error instead of a version banner:
which --version
Illegal option -- Usage: /usr/bin/which [-as] args
Use command -v which when you only need to confirm the executable exists. Use implementation-specific options only after checking the local help output or package documentation.
Troubleshoot Common which Command Errors
which Prints Nothing
No output usually means the command name is not an executable file in your current $PATH. Confirm the exit code when the output is blank:
which no-such-command
printf 'exit code: %s\n' "$?"
exit code: 1
First check whether the directory containing the executable appears in $PATH:
printf '%s\n' "$PATH"
A compact system $PATH may look like this:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
User-local commands often live in ~/.local/bin. If that directory is missing from $PATH, add it in the correct shell startup file for your login setup. If the file exists but lacks execute permission, fix the mode with chmod +x; use chmod command in Linux when you need a deeper permission workflow.
which Finds a Path but the Shell Runs Something Else
Aliases, shell functions, and built-ins can take priority over an external executable path. Compare which with type when behavior does not match the path you expected:
which echo
type echo
/usr/bin/echo echo is a shell builtin
The fix depends on the shell feature involved. Remove or rename an alias, adjust a shell function, or call the external binary by absolute path when you deliberately want to bypass the shell built-in.
which Shows a New Path but Bash Uses an Old One
Bash keeps a command hash table after it resolves executable paths. If an executable was removed or replaced while the shell session stayed open, Bash may still try the old cached path even though which now finds another match.
Clear Bash’s command hash table:
hash -r
Verify the cache is empty:
hash
hash: hash table empty
Illegal Option or Unrecognized Option
Option support depends on the implementation. Debian-family debianutils builds reject GNU-only options such as --version:
which --version
Illegal option -- Usage: /usr/bin/which [-as] args
BusyBox prints a longer help message for the same command; trimmed output includes the error and usage line:
which: unrecognized option '--version' Usage: which [-a] COMMAND...
Use which -a command_name for the portable multi-match behavior. Use GNU-only flags such as --skip-dot or --show-tilde only on systems where GNU which is installed.
Conclusion
With which, you can confirm the executable path your current $PATH resolves, spot duplicate binaries with -a, and avoid shell built-in confusion by switching to type or command -v when needed. For nearby lookup tasks, use whereis command in Linux when manual pages, source paths, or broader installed-file locations matter.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><blockquote>quote</blockquote>