Skip to content

Build a Bash Command-Line Tool with Options and Validation

A useful shell script should explain how to run it, validate its input, and return a clear status to the command that called it. This tutorial builds a small directory-usage tool that accepts a path with -d, checks that the directory exists, and prints its filesystem usage.

The example uses Bash and standard Linux utilities. It only reads filesystem metadata; it does not modify files or mount settings.


Step 1: Write the Script and Its Input Checks

01

Create a Script with Help and Error Functions

Script Structure

Save the following as dir-usage.sh. getopts parses short options, usage documents how to call the script, and die prints errors to standard error before returning a nonzero status. Quoting “$directory” keeps paths with spaces as one argument.

#!/usr/bin/env bash
set -Eeuo pipefail
usage() {
cat <<'USAGE'
Usage: dir-usage.sh [-d DIRECTORY] [-h]
Show filesystem usage for DIRECTORY. Defaults to the current directory.
-d DIRECTORY directory to inspect
-h show this help
USAGE
}
die() {
printf 'Error: %s\n' "$*" >&2
exit 2
}
directory='.'
while getopts ':d:h' option; do
case "$option" in
d) directory=$OPTARG ;;
h) usage; exit 0 ;;
:) die "option -$OPTARG requires a value" ;;
\?) die "unknown option: -$OPTARG" ;;
esac
done
shift "$((OPTIND - 1))"
(( $# == 0 )) || die 'unexpected positional argument; use -d PATH'
[[ -d "$directory" ]] || die "not a directory: $directory"
[[ -r "$directory" ]] || die "directory is not readable: $directory"
printf 'Filesystem usage for: %s\n' "$directory"
df -hP -- "$directory"
❯ View Expected Console Output
The script checks options and the target before running df.

Step 2: Make the Script Executable and Run It

02

Run the Tool with a Path Argument

Usage

Make the script executable, then pass a directory with -d. Quote the path if it contains spaces. Use -h to print help without inspecting a directory.

Terminal window
chmod u+x dir-usage.sh
./dir-usage.sh -d "$HOME/Project Files"
./dir-usage.sh -h
❯ View Expected Console Output
Filesystem usage for: /home/sam/Project Files
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 18G 20G 48% /

Step 3: Confirm the Failure Cases Are Clear

03

Check Syntax and Try Invalid Inputs

Validation

Run bash -n to check the script’s syntax without executing it. Then try a missing directory and an unsupported option. A useful error message should identify the bad input and exit nonzero so other scripts can detect the failure.

Terminal window
bash -n dir-usage.sh
./dir-usage.sh -d "$HOME/no-such-directory"
./dir-usage.sh -z
❯ View Expected Console Output
Error: not a directory: /home/sam/no-such-directory
Error: unknown option: -z

Step 4: Use Exit Statuses in Other Scripts

04

Branch on Whether the Tool Succeeded

Automation

A successful command returns status 0; nonzero statuses indicate a problem. Use an if statement to handle either result. This lets a larger script stop, retry, or report a failure instead of treating every command as successful.

Terminal window
if ./dir-usage.sh -d "$HOME"; then
printf 'Directory check completed.\n'
else
status=$?
printf 'Directory check failed with status %s.\n' "$status" >&2
fi
❯ View Expected Console Output
Directory check completed.

See the Bash Reference Manual for getopts, shell options, and parameter handling.

Comments