which Command in Linux: Find Executable Paths in PATH

which reports the pathname of an executable that would run for a given command name, searching directories in PATH in order. It answers which file the shell would start — not whether that file exists on disk in general.

Published

Updated

Read time 6 min read

Reviewed byDeepak Prasad

which Command in Linux: Find Executable Paths in PATH
About which reports the pathname of an executable that would run for a given command name, searching directories in PATH in order. It answers which file the shell would start — not whether that file exists on disk in general.
Tested on Ubuntu 25.04 (Plucky Puffin); debianutils which; kernel 7.0.0-27-generic
Package debianutils
Man page which(1)
Privilege none
Distros

Debian and Ubuntu ship which in the debianutils package.

Portable lookup with builtins: type and command -v in bash. Full-path search: locate and find.

which — quick reference

Lookup

Resolve command names against PATH — the same ordered search the shell uses when you type a bare name.

When to use Command
Print the first executable found for a command which grep
List every matching executable in PATH (not only the first) which -a grep
Resolve several commands in one invocation which ls bash sudo
Show the path to which itself which which

Shell integration

When to use Command
POSIX-friendly check in bash scripts (preferred over which) command -v grep
Show alias, function, or builtin resolution type grep
Print your PATH colon-separated list echo "$PATH"

Notes

which does not read man which --help on Debian — only -a and -s are supported. It ignores shell aliases unless you run it from a context where aliases are expanded.


which — command syntax

Usage from /usr/bin/which on Ubuntu 25.04 (debianutils):

text
which [-as] args

-a lists all matches in PATH order. -s returns only the exit status (quiet). There is no long --help flag on this build.


which — command examples

Essential Resolve one command

When a script fails with "command not found", which shows the binary the shell would execute if the name is on PATH.

bash
which grep

Sample output:

text
/usr/bin/grep

If nothing is found, which prints nothing and exits with status 1.

Essential All PATH matches (-a)

Some distributions install the same command under /usr/bin and /bin. Default which stops at the first hit; -a lists every match.

bash
which -a grep

Sample output:

text
/usr/bin/grep
/bin/grep

Use this when debugging unexpected versions — the first path wins for interactive PATH order.

Common Several commands at once

Pass multiple names to avoid repeated invocations in setup scripts.

bash
which ls bash sudo

Sample output:

text
/usr/bin/ls
/usr/bin/bash
/usr/bin/sudo

Each line corresponds to one argument in order.

Common Missing command — exit status

When the name is not executable on PATH, which is silent on stdout. Check $? in scripts.

bash
which nonexistent_cmd_xyz_42
echo "exit code: $?"

Sample output:

text
exit code: 1

Do not rely on parsing empty output alone in strict scripts — test the exit code.

Advanced Compare with type and command -v

which is an external program and may not see bash aliases or functions. type and command -v run inside the shell and are safer in bash scripts.

bash
type which
command -v grep
which grep

Sample output:

text
which is hashed (/usr/bin/which)
/usr/bin/grep
/usr/bin/grep

For aliases, type ls may show alias ls='…' while which ls still prints /usr/bin/ls if an alias is not exported to non-interactive paths.

Advanced Inspect PATH order

which only searches directories listed in PATH. Inspect the variable when results surprise you.

bash
echo "$PATH" | tr ':' '\n' | head -8

Sample output (order matters — first directories win):

text
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games

Put custom prefixes early when you need your build to shadow system binaries.


which — when to use / when not

Use which when Use something else when
You want a quick PATH lookup at the terminal You write bash scripts → prefer command -v
You need every duplicate binary (-a) You need man pages and source paths → whereis or find
You are checking after package install You search the whole disk by name → locate or find
You debug "wrong version" of a CLI tool You need file metadata → ls -l $(command -v tool)
You verify cron's minimal PATH Export PATH in the crontab or script — which only reflects current PATH

which vs command -v

which (debianutils) command -v (bash builtin)
Runs as External executable Shell builtin
Sees aliases/functions No Yes
POSIX scripts Discouraged Recommended
Lists all matches -a No (first resolution)
Speed in loops Spawns process Builtin — faster

Portable scripts should use command -v name and test $?.


Command One line
whereis Binary, source, and man paths
type Bash reserved word, function, alias, or file

Browse the full index in our Linux commands reference.


which — interview corner

What does the which command do?

which searches directories in the PATH environment variable, in order, for an executable file matching each argument. It prints the first path found, or with -a, every match.

It does not search the entire filesystem — only PATH entries.

A strong answer is:

"which walks PATH and prints the executable that would run for a name. -a shows every match; exit 1 if none."

Why do bash style guides prefer command -v over which?

which is an external program. It does not understand shell aliases or functions and may not exist in minimal containers. command -v is a POSIX builtin that resolves the same way the shell will execute the name.

bash
command -v git

A strong answer is:

"command -v is POSIX and builtin — it sees aliases and functions. which is an external PATH-only lookup; I use command -v in scripts."

When would you use which -a?

When multiple copies of a binary exist — for example /usr/bin/python3 and /usr/local/bin/python3. The first PATH entry wins for execution; -a reveals hidden alternates.

A strong answer is:

"which -a lists every PATH match — I use it when debugging wrong Python or Java versions shadowed earlier on PATH."

What exit code does which return when a command is missing?

It returns 1 when no executable is found and 0 when at least one argument resolves. Combine with $? in scripts instead of parsing empty output.

A strong answer is:

"Missing name → exit 1, found → 0. I test $? after command -v or which in scripts."

What does which not tell you?

It does not report man pages, libraries, or config paths (whereis does). It does not confirm the file is the right architecture, only that it is executable and named on PATH. It also ignores shell builtins unless you use type.

A strong answer is:

"which only resolves PATH executables — not man paths, not aliases, not whether the binary is correct for my arch. For scripts I use command -v; for broader search, whereis or locate."


Troubleshooting

Symptom Likely cause Fix
which prints nothing Name not on PATH or not executable Install package; fix PATH; use full path
Wrong version runs Earlier PATH directory shadows later one which -a cmd; reorder PATH or use absolute path
which differs from what runs Alias or function in interactive shell Run type cmd
Cron cannot find command Minimal cron PATH Set PATH= at top of crontab or use full path
Illegal option -- GNU which flags on debianutils build Use only -a and -s; see man page
Snap or flatpak binary missing Special paths not in script PATH Use distro package or export snap bin path

Rohan Timalsina

is a technical writer and Linux enthusiast who writes practical guides on Linux commands and system administration. He focuses on simplifying complex topics through clear explanations.