Vol. I · No. 46The command line sectionSat, 10 Oct 2026
Linux · navigation

which

where does this command live

which searches the directories in PATH, in order, and prints the first program that matches the name — the one the shell would run. It answers "is it installed, and which copy am I getting?"

When two versions are installed, which tells you the one you are actually running.

Searches
PATH
left to right
Prints
The first match
-a prints them all
Finds
Programs only
not builtins or aliases
Nothing printed
Not found
exit status 1

At the terminal

Read the session first, then the notes: each numbered line in the output is answered by the note with the same number.

user@netflow — bashdebianutils
$ which python3
1/usr/local/bin/python3
2$ which -a python3
/usr/local/bin/python3
/usr/bin/python3
3$ which cd
4$ type cd
cd is a shell builtin
Illustrative session · names, sizes and dates are examples, and every address is from a documentation or private range
Reading the output

What the numbered lines are telling you

1
The copy that runs

Typing python3 runs this file. It was found first because /usr/local/bin comes before /usr/bin in PATH.

2
-a shows every match

Two copies are installed. The system’s own is second, and is only reached by typing its full path.

3
No output for cd

cd is not a program on disk — it is built into the shell — so which finds nothing and prints nothing.

4
type knows more

type is part of the shell, so it also reports builtins, aliases and functions. Prefer it when which comes back empty.

Switches

A switch changes how the command behaves. These are the ones used day to day; man which lists the rest. Single-letter switches can usually be joined, so -l -a may be written -la.

-a
Print every match in PATH, not only the first.

Variations worth knowing

The same tool, pointed at a narrower question. These four cover most of what it is reached for day to day.

echo $PATH

Shows the directories that are searched, in order.

type -a ls

Shows everything the name means: alias, builtin and file.

command -v git

The portable form, for use in scripts.

ls -l $(which python3)

Shows whether the program found is a real file or a link to another.

In cybersecurity

The shell runs the first match in PATH, whoever put it there.

PATH hijacking

A program named ls placed in a directory that comes early in PATH runs instead of the real one. which shows when a common command resolves somewhere unexpected.

Never put . in PATH

With the current directory in PATH, entering a directory someone else controls can run their program in place of yours.

Use full paths in privileged scripts

A script run by root or cron should call /usr/bin/tar, not tar, so it cannot be redirected by a changed PATH.

Filed under

Navigation

Read alongside