Find out if a command exists on POSIX system Find out if a command exists on POSIX system shell shell

Find out if a command exists on POSIX system


command -v is a POSIX specified command that does what which does.

It is defined to to return >0 when the command is not found or an error occurs.


You could read the stdout/stderr of "which" into a variable or an array (using backticks) rather than checking for an exit code.

If the system does not have a "which" or "where" command, you could also grab the contents of the $PATH variable, then loop over all the directories and search for the given executable. That's essentially what which does (although it might use some caching/optimization of $PATH results).


A function_command_exists for checking if a command exists:

#!/bin/shset -eufunction_command_exists() {    local command="$1"    local IFS=":" # paths are delimited with a colon in $PATH    # iterate over dir paths having executables    for search_dir in $PATH    do        # seek only in dir (excluding subdirs) for a file with an exact (case sensitive) name        found_path="$(find "$search_dir" -maxdepth 1 -name "$command" -type f 2>/dev/null)"        # (positive) if a path to a command was found and it was executable        test -n "$found_path" && \        test -x "$found_path" && \            return 0    done        # (negative) if a path to an executable of a command was not found    return 1}# example usageecho "example 1";command="ls"if function_command_exists "$command"; then    echo "Command: "\'$command\'" exists"else    echo "Command: "\'$command\'" does not exist"ficommand="notpresent"if function_command_exists "$command"; then    echo "Command: "\'$command\'" exists"else    echo "Command: "\'$command\'" does not exist"fiecho "example 2";command="ls"function_command_exists "$command" && echo "Command: "\'$command\'" exists"command="notpresent"function_command_exists "$command" && echo "Command: "\'$command\'" does not exist"echo "End of the script"

output:

example 1Command: 'ls' existsCommand: 'notpresent' does not existexample 2Command: 'ls' existsEnd of the script

Note that even the set -eu that turns -e option for the script was used the script was executed to the last line "End of the script"

There is no Command: 'notpresent' does not exist in the example 2 because of the && operator so the execution of echo "Command: "\'$command\'" does not exist" is skipped but the execution of the script continues till the end.

Note that the function_command_exists does not check if you have a right to execute the command. This needs to be done separately.

Solution with command -v <command-to-check>

#!/bin/shset -eu;# check if a command exists (Yes)command -v echo > /dev/null && status="$?" || status="$?"if [ "${status}" = 127 ]; then   echo "<handle not found 1>"fi# check if a command exists (No)command -v command-that-does-not-exists > /dev/null && status="$?" || status="$?"if [ "${status}" = 127 ]; then   echo "<handle not found 2>"fi

produces:

<handle not found 2>

because echo was found at the first example.

Solution with running a command and handling errors including command not found.

#!/bin/shset -eu;# check if a command exists (No)command -v command-that-does-not-exist > /dev/null && status="$?" || status="$?"if [ "${status}" = 127 ]; then   echo "<handle not found 2>"fi# run command and handle errors (no problem expected, echo exist)echo "three" && status="$?" || status="$?"if [ "${status}" = 127 ]; then   echo "<handle not found 3>"elif [ "${status}" -ne 0 ]; then   echo "<handle other error 3>"fi# run command and handle errors (<handle not found 4> expected)command-that-does-not-exist && status="$?" || status="$?"if [ "${status}" = 127 ]; then   echo "<handle not found 4>"elif [ "${status}" -ne 0 ]; then   echo "<handle other error 4>"fi# run command and handle errors (command exists but <handle other error 5> expected)ls non-existing-path && status="$?" || status="$?"if [ "${status}" = 127 ]; then   echo "<handle not found 5>"elif [ "${status}" -ne 0 ]; then   echo "<handle other error 5>"fi

produces:

<handle not found 2>three./function_command_exists.sh: 34: ./function_command_exists.sh: command-that-does-not-exist: not found<handle not found 4>ls: cannot access 'non-existing-path': No such file or directory<handle other error 5>