How to Check if a Command Exists in Bash

By 

Published on

5 min read

Bash command existence check using command -v in a shell script

Scripts often depend on tools such as git, curl, jq, or docker. If one of those commands is missing, Bash usually fails later with command not found, which can be hard to diagnose if the script has already created files, changed directories, or started a deployment step.

A small dependency check at the top of the script gives you a cleaner failure path. You can print a useful error, exit with a non-zero status, or install the missing package in setup scripts that are meant to manage the local machine.

This guide shows the reliable command -v pattern, how to capture the resolved path, and when alternatives such as type, hash, and which make sense.

For scripts, the safest default is to run command -v and test its exit status:

sh
if command -v git >/dev/null 2>&1; then
    echo "git is available"
else
    echo "git is not installed" >&2
    exit 1
fi

command -v NAME exits with status 0 when the shell can resolve NAME as a command. If the name is not found, it exits with a non-zero status. Redirecting both stdout and stderr to /dev/null hides the resolved path or lookup message, so the check stays quiet unless you print your own error.

In Bash, command -v can find executables on PATH, shell builtins, functions, and shell keywords. It may also report aliases in shells where alias expansion is enabled, but scripts should not treat aliases as required dependencies. Check for the actual command your script will run.

Capture the Path

When you need the resolved command path later in the script, assign the output inside the if condition:

sh
if git_bin=$(command -v git); then
    echo "git found at: $git_bin"
else
    echo "git is required but was not found" >&2
    exit 1
fi

For external programs, the variable contains the path that Bash found through PATH, such as /usr/bin/git. For builtins and functions, command -v may return the command name instead of a filesystem path.

This pattern keeps the check and the assignment tied together. Avoid assigning first and checking only whether the variable is non-empty, because the exit status tells you exactly whether the lookup succeeded.

Check Multiple Commands

When a script depends on several external programs, validate all of them before doing any work. In a Bash script, an array keeps the command list clear:

sh
required_commands=(git curl jq)
missing_commands=()

for cmd in "${required_commands[@]}"; do
    if ! command -v "$cmd" >/dev/null 2>&1; then
        missing_commands+=("$cmd")
    fi
done

if ((${#missing_commands[@]} > 0)); then
    printf 'Error: missing required commands: %s\n' "${missing_commands[*]}" >&2
    exit 1
fi

The loop records every missing command, then prints them on a single stderr line with >&2. The ${missing_commands[*]} expansion joins the names with a space, so all missing dependencies appear in one message. Exiting before the main work begins prevents partial runs and gives callers a clear failure status. For more on exit values, see the Bash exit code guide .

Install a Missing Command

For local setup scripts, you may want to install a dependency when it is missing. On Ubuntu, Debian, and derivatives, the pattern looks like this:

sh
if ! command -v jq >/dev/null 2>&1; then
    echo "jq not found, installing..."
    sudo apt update
    sudo apt install -y jq
fi

Use auto-install logic only in scripts where changing the system is expected, such as a bootstrap script for a development machine or server. For general-purpose scripts, print the missing dependency and let the user decide how to install it.

Alternative: type

type is a Bash builtin that shows how a command name will be interpreted:

sh
if type git >/dev/null 2>&1; then
    echo "git is available"
fi

This behaves similarly to command -v for a basic existence check, but type is mainly useful when you want explanation output for a person. For example, it can show whether a name is a builtin, function, alias, keyword, or executable file.

If you specifically need an executable file on PATH in Bash, use type -P:

sh
if type -P git >/dev/null 2>&1; then
    echo "git executable found"
fi

The type command is useful for debugging shell name resolution. For a deeper look at its options, see the type command guide .

Alternative: hash

hash is another Bash builtin that can resolve command names and remember executable paths in the shell’s hash table:

sh
if hash git 2>/dev/null; then
    echo "git is available"
fi

This can work for quick Bash-only checks, but it is less clear than command -v and is not the best general-purpose pattern. Do not use hash -t name as the first lookup, because -t prints an entry only after the command has already been hashed in the current shell.

Use command -v unless you specifically need to inspect or manage Bash’s command hash table.

Why Not which

which is common in interactive terminal use, but it is not the best choice inside scripts:

sh
# Avoid this in scripts
if which git >/dev/null 2>&1; then
    echo "git found"
fi

Unlike command -v, which is usually an external program and is not standardized by POSIX. Its behavior and output can vary between systems, and it may not reflect Bash functions, builtins, or aliases the same way the shell does.

Use which when you are typing at a prompt and only want a quick path lookup. Use command -v when the result controls script logic.

Quick Reference

TaskPattern
Check whether a command existscommand -v name >/dev/null 2>&1
Check and branchif command -v name >/dev/null 2>&1; then ... fi
Capture the resolved pathif name_bin=$(command -v name); then ... fi
Check several commands in Bashfor c in git curl jq; do command -v "$c"; done
Print dependency errorsecho "missing command" >&2
Check for an executable file in Bashtype -P name >/dev/null 2>&1
Avoid for script logicwhich name

Conclusion

Use command -v at the start of Bash scripts that depend on external programs, then fail early with a clear stderr message when a dependency is missing. For broader script guardrails, see our Bash best practices guide.

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page