Why “which” returns none on some commands I can run? [duplicate]
I found
which alias
orwhich compgen
etc returns nothing.
Both of those are shell builtins. which
knows nothing of shell builtins: it simply searches a path for executables.
For a more reliable result, use type
.
$ type compgen
compgen is a shell builtin
$ type alias
alias is a shell builtin
type
has better knowledge of what executes because it is a shell builtin.
Why which
is unreliable
which
often gives the wrong answer. Observe:
$ type pwd
pwd is a shell builtin
$ which pwd
/bin/pwd
When you run pwd
, without specifying an explicit path, the shell will execute its builtin, not the executable that which
found.
Here are more examples of which
giving the wrong answer:
$ type echo
echo is a shell builtin
$ which echo
/bin/echo
$ type [
[ is a shell builtin
$ which [
/usr/bin/[
Observe:
$ type /bin/echo
/bin/echo is /bin/echo
When you give an explicit path for echo
, such as /bin/echo
, then the shell would run that executable, not its builtin. type
knows that also, as you can see above.
How which
works internally
On debian-like systems, which
is a simple shell script, The relevant part of which is:
for ELEMENT in $PATH; do
if [ -z "$ELEMENT" ]; then
ELEMENT=.
fi
if [ -f "$ELEMENT/$PROGRAM" ] && [ -x "$ELEMENT/$PROGRAM" ]; then
puts "$ELEMENT/$PROGRAM"
RET=0
[ "$ALLMATCHES" -eq 1 ] || break
fi
done
As you can see, it does a simple search along the PATH for an executable file of the name given.