How to Check if Command Exists
Quick Answer: Check if Command Exists in Bash
To check if a command exists, use command -v commandname &>/dev/null. If it returns true, the command exists. Example: if command -v python &>/dev/null; then … This is the most portable and reliable method.
Quick Comparison: Command Checking Methods
| Method | Syntax | Reliability | Portability | Best For |
|---|---|---|---|---|
| command -v | command -v cmd | Excellent | Universal | Most cases |
| type | type cmd | Very good | Most shells | Shell builtins |
| which | which cmd | Good | Most systems | Quick check |
| hash | hash cmd | Good | Bash only | Cached commands |
Bottom line: Use command -v for maximum portability and reliability.
Why Check if a Command Exists?
Before using a command in a script, you should verify it exists on the system. Not all systems have the same tools installed. For example, some Linux distributions might have curl but not wget, or vice versa. Checking for command availability prevents confusing “command not found” errors and lets you handle missing tools gracefully.
Method 1: Using the command Builtin (Recommended)
The command builtin is the most reliable way to check if a command exists:
#!/bin/bash
# Check if python is available
if command -v python &>/dev/null; then
echo "Python is installed"
else
echo "Python is not installed"
fi
# Check if docker exists
if command -v docker &>/dev/null; then
echo "Docker is available"
else
echo "Docker is not available"
fi
The -v flag returns the path to the command if it exists, or nothing if it doesn’t. We redirect output to /dev/null to suppress the output and only use the exit code.
Practical Example: Fallback Commands
Here’s a real-world scenario - trying multiple tools and falling back to alternatives:
#!/bin/bash
# Try to use the best available option for JSON pretty-printing
pretty_json() {
if command -v jq &>/dev/null; then
# Best option - jq is fast and powerful
jq '.' <<< "$1"
elif command -v python &>/dev/null; then
# Fallback to Python
python -m json.tool <<< "$1"
elif command -v python3 &>/dev/null; then
# Another Python option
python3 -m json.tool <<< "$1"
else
# Last resort - just output as-is
echo "$1"
fi
}
# Usage
pretty_json '{"name": "John", "age": 30}'
Checking Multiple Commands
When your script requires several tools, check them all at startup:
#!/bin/bash
# Required commands for the script to work
REQUIRED_COMMANDS=("curl" "grep" "sed" "awk")
# Check if all required commands exist
for cmd in "${REQUIRED_COMMANDS[@]}"; do
if ! command -v "$cmd" &>/dev/null; then
echo "ERROR: Required command '$cmd' is not installed"
exit 1
fi
done
echo "All required commands are available"
# Continue with script...
This is much cleaner than checking each command individually with separate if statements.
Real-World Example: Package Manager Detection
Detect which package manager is available:
#!/bin/bash
install_package() {
local package="$1"
if command -v apt-get &>/dev/null; then
echo "Using apt-get..."
sudo apt-get update
sudo apt-get install -y "$package"
elif command -v yum &>/dev/null; then
echo "Using yum..."
sudo yum install -y "$package"
elif command -v brew &>/dev/null; then
echo "Using brew..."
brew install "$package"
else
echo "ERROR: No supported package manager found"
return 1
fi
}
# Usage
install_package "git"
Getting the Command Path
Sometimes you want the actual path to the command:
#!/bin/bash
# Get the full path to a command
if cmd_path=$(command -v python3); then
echo "Python 3 is located at: $cmd_path"
else
echo "Python 3 not found"
fi
# This could output: /usr/bin/python3
Alternative: Using which
While which also checks for commands, command is preferred because it’s more portable:
# Less reliable - doesn't work in all contexts
which python
# More reliable - recommended
command -v python
Checking for Specific Command Features
Sometimes you need a specific version or capability:
#!/bin/bash
# Check for grep and ensure it supports -E (extended regex)
if command -v grep &>/dev/null && grep -E . &>/dev/null; then
echo "grep with extended regex support is available"
fi
# Check for bash version 4 or higher
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
echo "Bash 4+ is available"
else
echo "Bash 3 or older - some features unavailable"
fi
Practical Example: System Diagnostic Script
#!/bin/bash
echo "=== System Diagnostic ==="
echo ""
# List of optional tools and what they do
TOOLS=("curl:Network requests" "wget:Downloading files" "git:Version control" "docker:Containerization" "node:JavaScript runtime")
for tool_info in "${TOOLS[@]}"; do
tool="${tool_info%:*}"
description="${tool_info#*:}"
if command -v "$tool" &>/dev/null; then
echo "âś“ $tool - $description"
else
echo "âś— $tool - NOT INSTALLED ($description)"
fi
done
Output:
=== System Diagnostic ===
âś“ curl - Network requests
âś— wget - NOT INSTALLED (Downloading files)
âś“ git - Version control
âś“ docker - Containerization
âś— node - NOT INSTALLED (JavaScript runtime)
Important Notes
- Use
command -vin portable scripts - The
&>/dev/nullredirects both stdout and stderr, suppressing output - Exit code 0 means the command exists, non-zero means it doesn’t
- Always quote command names:
command -v "$cmd"notcommand -v $cmd commandis a shell builtin - it’s always available
Quick Reference
# Check if command exists and continue if it does
if command -v docker &>/dev/null; then
docker ps
fi
# Check and exit if command doesn't exist
if ! command -v gcc &>/dev/null; then
echo "GCC compiler not found"
exit 1
fi
# Get the path to a command
PATH_TO_CMD=$(command -v python3)
# Check if one of several commands exists
for cmd in python python3 python2; do
if command -v "$cmd" &>/dev/null; then
echo "Found: $cmd"
break
fi
done
Summary
Checking if commands exist before using them makes your scripts more robust and portable. Use command -v to verify tools are available, provide fallbacks for alternatives, and give clear error messages when required tools are missing. This is especially important when distributing scripts across different systems.