The which & type command in Linux
When several versions of a tool coexist (system python, pyenv python, a venv), which prints the one your PATH resolves to. type goes further: it reveals whether a name is an alias, a shell function, a built-in or a file: the truth behind "why does this command behave differently for me?".
How which & type works
which is an outsider: a separate program that walks PATH looking for an executable file with the given name, reporting the first hit. It reproduces the shell's file search, and only that. The shell itself resolves names through a richer sequence first: aliases, functions, builtins, then a cached hash table of previously found commands, and only then PATH.
type is the insider: a builtin with access to all those tables, which is why its answer is the truth about what will actually run. The hash table adds one classic wrinkle: after installing a new version of a tool elsewhere on PATH, a long-lived shell may keep executing the cached old path until "hash -r" clears it. When which, type and reality disagree, the cache is usually the missing suspect.
Syntax
which COMMAND | type [-a] COMMAND Common options
| Option | What it does |
|---|---|
which cmd | The path of the file that would execute. |
type cmd | What KIND of thing the name is (alias/function/builtin/file). |
type -a cmd | Every match on PATH, in resolution order. |
command -v cmd | The POSIX, script-safe spelling. |
How to use which & type: examples
$ which python3 Exactly which interpreter runs: the first question of every environment mixup.
$ type ll "ll is aliased to ls -lah": unmask the shortcut.
$ type -a python All pythons on PATH in order: the shadowing map.
$ command -v docker >/dev/null || echo "docker not installed" The portable existence check for scripts.
Real-world use cases for which & type
The version-mixup exorcism
Team member "has the new node but old runs": type -a node reveals three installs and their order; which shows the winner; a PATH reorder in .bashrc ends the séance. Ninety seconds, recurring ticket closed.
Script prerequisites
Portable scripts open with checks: command -v jq >/dev/null || { echo "jq required" >&2; exit 1; }. Failing loudly at line 3 beats failing weirdly at line 300.
Pro tips and common mistakes
- Trust type over which, only type sees aliases, functions and builtins.
- In scripts, command -v is the POSIX-portable existence test.
- New install not taking effect in an old shell? hash -r clears the command cache.
Frequently asked questions about which & type
which shows one thing but something else runs?
An alias or function shadows it, which only searches PATH files. type sees the whole picture; trust type.
How do scripts test for a command?
command -v name. POSIX, silent, exit-code driven. which is unreliable across systems for this.
Errors you may hit with which & type
The shell searched every directory in your PATH and found no executable with that name.
bad interpreter: No such file or directoryWindows line endings make the shebang point at an interpreter that does not exist.
Related commands
Search, install, upgrade and remove packages, plus the dnf/pacman equivalents.
env & exportHow configuration flows into processes. PATH, export, and why edits "don't stick".
aliasName your habits: shortcuts, safer defaults, and where to keep them.
Concepts behind which & type: PATH