whichis non-standard. Use builtin
This is an optional suggestion. It must be explicitly enabled with a directive
enable=deprecate-which in a
# shellcheck comment or
# 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 -vdoes not check ALL parameters
command -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
shellcheckissue: #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.