which
is non-standard. Use builtin command -v
instead.This is an optional suggestion. It must be
explicitly enabled with a directive
enable=deprecate-which
in a # shellcheck
comment or .shellcheckrc
which grep
# For the path of a single, unaliased, external command,
# or to check whether this will just "run" in this shell:
command -v grep
# To check whether commands exist, without obtaining a reusable path:
hash grep
which
is a non-standard, external tool that locates an
executable in PATH. command -v
is a POSIX standard builtin,
which uses the same lookup mechanism that the shell itself would.
This check is opt-in only in 0.7.1+, and you may choose to ignore it in earlier versions. which
is
very common, and some prefer its executable-or-nothing behavior over
command -v
's handling of builtins, functions and
aliases.
command -v
does not check ALL parameterscommand -v
succeeds (with exit code 0) if any
command exists:
# grep is in /usr/bin/grep
# foobar is not in path
#
$ command -v -- grep foobar; echo $?
0
In the above example, it should have failed and exited with 1 unless
all commands exist, if it were to be a replacement for
which
. Other problems associated with command
include its inclusion of builtins, aliases, and functions.
An alternative is:
$ hash <file1> <file2>
Which observes the standard behaviour of failures.
To obtain a path, type -p
can be used instead. Like
command -v
, it has a similarly quirky behavior with
builtins, aliases, and functions, although this is arguably milder since
it would print nothing for these cases. The failure condition is similar
to hash
.
shellcheck
issue: #1162 command
-v is not a direct replacement for which (Discussion)ShellCheck is a static analysis tool for shell scripts. This page is part of its documentation.