<> == How can I determine whether a command exists anywhere in my PATH? == POSIX specifies a shell builtin called `command` which can be used for this purpose: {{{ # POSIX if command -v qwerty >/dev/null; then echo qwerty exists else echo qwerty does not exist fi }}} In BASH, there are a couple more builtins that may also be used: `hash` and `type`. Here's an example using `hash`: {{{ # Bash if hash qwerty 2>/dev/null; then echo qwerty exists else echo qwerty does not exist fi }}} Or, if you prefer `type`: {{{ # Bash # type -P forces a PATH search, skipping builtins and so on if type -P qwerty >/dev/null; then echo qwerty exists else echo qwerty does not exist fi }}} KornShell and zsh have `whence` instead: {{{ # ksh/zsh if whence -p qwerty >/dev/null; then echo qwerty exists else echo qwerty does not exist fi }}} The `command` builtin also returns true for shell builtins (unlike `type -P`). If you absolutely must check only PATH, the only POSIX way is to iterate over it: {{{ # POSIX IsInPath () ( [ "$#" = 1 ] && [ "$1" ] || return 2 set -f; IFS=: for dir in $PATH$IFS; do [ -x "${dir:-.}/$1" ] && return done return 1 ) if IsInPath qwerty; then echo qwerty exists else echo qwerty does not exist fi }}} Note that the function defined above uses parentheses around the body rather than the normal curly braces. This makes the body run in a subshell, and is the reason we don't need to undo `set -f` or [[IFS]]. The iterative approach is also used in `configure` scripts. Here's a ''simplified'' version of such a test: {{{ # Bourne save_IFS=$IFS IFS=: found=no for dir in $PATH; do if test -x "$dir/qwerty"; then echo "qwerty is installed (in $dir)" found=yes break fi done IFS=$save_IFS if test "$found" = no; then echo "qwerty is not installed" fi }}} Real `configure` scripts are generally much more complicated than this, since they may deal with systems where `$PATH` is not delimited by colons; or systems where executable programs may have optional extensions like `.EXE`; or `$PATH` variables that have the current working directory included in them as an empty string; etc. If you're interested in such things, I suggest reading an actual GNU autoconf-generated `configure` script. They're far too large and complicated to include in this FAQ. The command `which` (which is often a csh script, although sometimes a compiled binary) is '''not reliable''' for this purpose. `which` may not set a useful exit code, and it may not even write errors to stderr. Therefore, in order to have a prayer of successfully using it, one must parse its output (wherever that output may be written). {{{ # Bourne. Last resort -- using which(1) tmpval=`LC_ALL=C which qwerty 2>&1` if test "$?" -ne 0; then # FOR NOW, we'll assume that if this machine's which(1) sets a nonzero # exit status, that it actually failed. I've yet to see any case where # which(1) sets an erroneous failure -- just erroneous "successes". echo "qwerty is not installed. Please install it." else # which returned 0, but that doesn't mean it succeeded. Look for known error strings. case "$tmpval" in *no\ *\ in\ *|*not\ found*|'') echo "qwerty is not installed. Please install it." ;; *) echo "Congratulations -- it seems you have qwerty (in $tmpval)." ;; esac fi }}} Note that `which(1)`'s output when a command is not found is ''not'' consistent across platforms. On HP-UX 10.20, for example, it prints {{{no qwerty in /path /path /path ...}}}; on OpenBSD 4.1, it prints {{{qwerty: Command not found.}}}; on Debian (3.1 through 5.0 at least) and SuSE, it prints nothing at all; on Red Hat 5.2, it prints {{{which: no qwerty in (/path:/path:...)}}}; on Red Hat 6.2, it writes the same message, but on standard error instead of standard output; and on Gentoo, it writes something on stderr. We '''strongly recommend''' not using `which`. Use one of the builtins or the iterative approaches instead.