Command-Line Arguments and Options in Shell Script: Building Flexible Bash Tools

Last updated at: September 08, 2024
Written by: Abdul

Introduction to Command-Line Arguments and Options

Command-line arguments and options are essential for creating flexible and user-friendly shell Script. They allow users to customize script behavior without modifying the script itself. In this article, we'll explore how to effectively handle command-line input in Bash Script.

Accessing Command-Line Arguments

Bash provides special variables to access command-line arguments:

#!/bin/bash

echo "Script name: $0"
echo "First argument: $1"
echo "Second argument: $2"
echo "Number of arguments: $#"
echo "All arguments: $@"

Parsing Command-Line Options with getopts

The 'getopts' built-in command is a powerful tool for parsing command-line options:

#!/bin/bash

while getopts ":a:b:c" opt; do
  case $opt in
    a)
      echo "Option -a was triggered, Parameter: $OPTARG"
      ;;
    b)
      echo "Option -b was triggered, Parameter: $OPTARG"
      ;;
    c)
      echo "Option -c was triggered"
      ;;
    \?)
      echo "Invalid option: -$OPTARG"
      ;;
    :)
      echo "Option -$OPTARG requires an argument."
      ;;
  esac
done

This script can handle options like: ./script.sh -a foo -b bar -c

Handling Long Options

For long options (e.g., --help), we can use a combination of pattern matching and shift:

#!/bin/bash

while [[ $# -gt 0 ]]; do
  case $1 in
    --help)
      echo "Usage: $0 [--help] [--version] [--file FILE]"
      exit 0
      ;;
    --version)
      echo "Script Version 1.0"
      exit 0
      ;;
    --file)
      FILE="$2"
      shift # Remove --file from processing
      ;;
    *)
      echo "Unknown option: $1"
      exit 1
      ;;
  esac
  shift
done

if [[ -n $FILE ]]; then
  echo "File specified: $FILE"
else
  echo "No file specified"
fi

Combining Short and Long Options

We can combine both short and long option handling for maximum flexibility:

#!/bin/bash

# Default values
VERBOSE=false
OUTPUT_FILE=""

# Parse options
while getopts ":hvo:" opt; do
  case $opt in
    h)
      echo "Usage: $0 [-h] [-v] [-o output_file] [file ...]"
      exit 0
      ;;
    v)
      VERBOSE=true
      ;;
    o)
      OUTPUT_FILE=$OPTARG
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done

# Remove options from argument list
shift $((OPTIND-1))

# Process remaining arguments (files)
for file in "$@"; do
  if $VERBOSE; then
    echo "Processing file: $file"
  fi
  # Process file here
done

if [[ -n $OUTPUT_FILE ]]; then
  echo "Output will be written to: $OUTPUT_FILE"
fi

Practical Example: File Backup Script

Let's create a practical script that demonstrates the use of command-line arguments and options for a file backup tool:

#!/bin/bash

# Default values
BACKUP_DIR="./backup"
COMPRESS=false
VERBOSE=false

# Function to display usage
usage() {
    echo "Usage: $0 [-d backup_dir] [-c] [-v] file [file ...]"
    echo "  -d: Specify backup directory (default: ./backup)"
    echo "  -c: Compress backup files"
    echo "  -v: Verbose mode"
    exit 1
}

# Parse options
while getopts ":d:cv" opt; do
    case $opt in
        d) BACKUP_DIR="$OPTARG" ;;
        c) COMPRESS=true ;;
        v) VERBOSE=true ;;
        \?) echo "Invalid option: -$OPTARG" >&2; usage ;;
        :) echo "Option -$OPTARG requires an argument." >&2; usage ;;
    esac
done

# Remove options from argument list
shift $((OPTIND-1))

# Check if files are specified
if [ $# -eq 0 ]; then
    echo "Error: No files specified for backup." >&2
    usage
fi

# Create backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"

# Backup files
for file in "$@"; do
    if [ -f "$file" ]; then
        backup_file="$BACKUP_DIR/$(basename "$file").$(date +%Y%m%d_%H%M%S)"
       
        if $COMPRESS; then
            gzip -c "$file" > "$backup_file.gz"
            backup_file="$backup_file.gz"
        else
            cp "$file" "$backup_file"
        fi
       
        if $VERBOSE; then
            echo "Backed up: $file to $backup_file"
        fi
    else
        echo "Warning: $file does not exist or is not a regular file." >&2
    fi
done

echo "Backup completed."

Conclusion

Mastering command-line arguments and options is crucial for creating flexible and user-friendly shell Script. By implementing robust argument parsing, you can build powerful Bash tools that adapt to user needs without requiring script modifications. This skill is essential for creating professional-grade shell Script and command-line interfaces.

In our next article, we'll explore error handling and debugging techniques in shell Script, helping you create more robust and reliable Bash tools. Stay tuned!