CrackOps
Interview PrepTracksLinuxAWS LabSoonInterview RoomSoon
Sign inStart free
CrackOps

Interview prep for the people who keep production up.

[email protected]
ProductInterview PrepTracksDashboardInterview Room
RolesDevOpsSREPlatformCloud
CompanyAboutContactPrivacyTerms
© CrackOps
Linux / Environment & Shell / which

which

Find which executable runs for a command name

Beginnershellpathtroubleshooting

which searches the directories in PATH and prints the first executable file matching a command name, or all of them with -a. It answers 'which python3 or terraform am I actually running?', but it knows nothing about aliases, functions or shell builtins.

Syntaxwhich [-a] COMMAND...

Watch it run

pip installs land in one Python but your script runs another. Find all copies and which one wins.

devops@devops-lab: ~ — zsh — 96×28
➜ ~
Step 1 of 3
which python3

The first python3 in PATH. /usr/local/bin comes before /usr/bin in Ubuntu's default PATH, so a locally built Python wins.

Anatomy of a command

$
commandwhich

On Ubuntu a small shell script from debianutils; on RHEL a separate program. Either way it only searches PATH.

How it works

which splits $PATH on colons and, for each directory in order, checks whether DIR/name exists and is an executable regular file (a stat plus an access check). It prints the first hit, or every hit with -a, and exits 0 if all names were found, 1 otherwise. That's the same search the kernel-facing part of the shell does before execve, which is why which is useful when two versions are installed. But which runs as a separate process, so it can't see the shell's aliases, functions, builtins or hash table. It says nothing for cd, and for ls it shows /usr/bin/ls even though your shell runs the alias ls --color=auto. On merged-/usr systems like Ubuntu 24.04, /bin is a symlink to /usr/bin, so which -a often shows the same file twice. For what the shell will really do, use type (or command -v in scripts). Remember bash caches lookups in a hash table, so after you install a new copy earlier in PATH, the shell may keep running the old one until hash -r.

Options you'll actually use

which NAMEFirst match in PATH
-aAll matches, in PATH order
exit status0 found, 1 not found (no output)
type -a NAMEWhat the shell will really run (aliases, builtins too)
command -v NAMEPOSIX, script-friendly lookup
hash -rForget bash's cached command paths
readlink -f $(which NAME)Resolve symlinks to the real binary

Common mistakes

Using which to check if a command exists in a script

which is an external program whose output and exit codes differ between distros, and some versions print 'no X in (...)' to stdout.

command -v kubectl >/dev/null 2>&1 || { echo 'kubectl missing' >&2; exit 1; }
Trusting which for aliases or functions

which only searches PATH; your shell may run an alias or function with the same name.

type -a NAME
Reinstalling a tool because the old version still runs

bash's hash table remembers the old path.

hash -r (or hash -d NAME), then check with type

Interview questions

Practice

Try these on a Linux machine of your own. Each task has a hint and a solution.

  1. 1

    Find where bash, python3 and jq live, and list every copy of python3 in PATH.

  2. 2

    Show that which knows nothing about builtins: compare which cd and type cd.

  3. 3

    Write a one-line check that prints 'missing: htop' if htop isn't installed, in a way suitable for scripts.

Related commands

typeSee exactly what the shell will run for a nameexportPass variables to the programs you startaliasCreate shortcuts for commands you type all the timeenvShow the environment, or run a command with a changed one
PreviousunsetNexttype
Linux / Environment & Shell / which

which

Find which executable runs for a command name

Beginnershellpathtroubleshooting

which searches the directories in PATH and prints the first executable file matching a command name, or all of them with -a. It answers 'which python3 or terraform am I actually running?', but it knows nothing about aliases, functions or shell builtins.

Syntaxwhich [-a] COMMAND...

Watch it run

pip installs land in one Python but your script runs another. Find all copies and which one wins.

devops@devops-lab: ~ — zsh — 96×28
➜ ~
Step 1 of 3
which python3

The first python3 in PATH. /usr/local/bin comes before /usr/bin in Ubuntu's default PATH, so a locally built Python wins.

Anatomy of a command

$
commandwhich

On Ubuntu a small shell script from debianutils; on RHEL a separate program. Either way it only searches PATH.

How it works

which splits $PATH on colons and, for each directory in order, checks whether DIR/name exists and is an executable regular file (a stat plus an access check). It prints the first hit, or every hit with -a, and exits 0 if all names were found, 1 otherwise. That's the same search the kernel-facing part of the shell does before execve, which is why which is useful when two versions are installed. But which runs as a separate process, so it can't see the shell's aliases, functions, builtins or hash table. It says nothing for cd, and for ls it shows /usr/bin/ls even though your shell runs the alias ls --color=auto. On merged-/usr systems like Ubuntu 24.04, /bin is a symlink to /usr/bin, so which -a often shows the same file twice. For what the shell will really do, use type (or command -v in scripts). Remember bash caches lookups in a hash table, so after you install a new copy earlier in PATH, the shell may keep running the old one until hash -r.

Options you'll actually use

which NAMEFirst match in PATH
-aAll matches, in PATH order
exit status0 found, 1 not found (no output)
type -a NAMEWhat the shell will really run (aliases, builtins too)
command -v NAMEPOSIX, script-friendly lookup
hash -rForget bash's cached command paths
readlink -f $(which NAME)Resolve symlinks to the real binary

Common mistakes

Using which to check if a command exists in a script

which is an external program whose output and exit codes differ between distros, and some versions print 'no X in (...)' to stdout.

command -v kubectl >/dev/null 2>&1 || { echo 'kubectl missing' >&2; exit 1; }
Trusting which for aliases or functions

which only searches PATH; your shell may run an alias or function with the same name.

type -a NAME
Reinstalling a tool because the old version still runs

bash's hash table remembers the old path.

hash -r (or hash -d NAME), then check with type

Interview questions

Practice

Try these on a Linux machine of your own. Each task has a hint and a solution.

  1. 1

    Find where bash, python3 and jq live, and list every copy of python3 in PATH.

  2. 2

    Show that which knows nothing about builtins: compare which cd and type cd.

  3. 3

    Write a one-line check that prints 'missing: htop' if htop isn't installed, in a way suitable for scripts.

Related commands

typeSee exactly what the shell will run for a nameexportPass variables to the programs you startaliasCreate shortcuts for commands you type all the timeenvShow the environment, or run a command with a changed one
PreviousunsetNexttype