Bash Command Line Arguments

Passing data to your Bash scripts

📥 What are Command Line Arguments?

Command line arguments are values passed to a script when you run it. They allow scripts to accept input from users, making them flexible and reusable for different situations.

#!/bin/bash
# Simple argument example
echo "Hello, $1!"

Usage:

$ ./script.sh John
Hello, John!

Key Argument Concepts

1️⃣

Positional Arguments

Access arguments by position

echo $1 $2 $3
🔢

Argument Count

Check how many arguments passed

echo "Args: $#"
📦

All Arguments

Access all arguments at once

echo "$@"
📝

Script Name

Get the script's own name

echo "$0"

🔹 Basic Positional Arguments

Positional arguments $1, $2, etc., are the simplest way to pass input into a script. They correspond directly to the order of arguments on the command line. For example, in ./script.sh file.txt backup, $1 is "file.txt" and $2 is "backup". This direct mapping makes scripts intuitive to use for basic tasks like file processing, where arguments often represent sources, destinations, or operation modes.

#!/bin/bash
# greet.sh - Greet a user
echo "First name: $1"
echo "Last name: $2"
echo "Full name: $1 $2"

Usage & Output:

$ ./greet.sh John Doe
First name: John
Last name: Doe
Full name: John Doe

🔹 Special Variables

Bash provides a set of built-in special variables that offer immediate access to script and system metadata without explicit declaration. These include $0 for the script name, $1-$9 for positional arguments, $? for the exit status of the last command, $$ for the current process ID, and $# for the argument count. They are automatically populated by the shell and are indispensable for handling command-line inputs, debugging, and process control. Using special variables makes scripts more interactive, error-aware, and easier to debug.

#!/bin/bash
# args-info.sh
echo "Script name: $0"
echo "Number of arguments: $#"
echo "All arguments: $@"
echo "First argument: $1"
echo "Process ID: $$"

Usage & Output:

$ ./args-info.sh apple banana cherry
Script name: ./args-info.sh
Number of arguments: 3
All arguments: apple banana cherry
First argument: apple
Process ID: 12345

🔹 Checking Argument Count

Validating the number of arguments ($#) is a crucial first step for robust scripts. It prevents errors from missing or excessive inputs. A common pattern is: if [ $# -ne 2 ]; then echo "Usage: $0 source dest"; exit 1; fi. This provides immediate, clear feedback to the user, guiding them toward correct usage and preventing the script from proceeding with invalid data, which could cause data loss or unexpected behavior.

#!/bin/bash
# check-args.sh
if [ $# -eq 0 ]; then
    echo "Error: No arguments provided"
    echo "Usage: $0 <name>"
    exit 1
fi

echo "Hello, $1!"

Usage & Output:

$ ./check-args.sh
Error: No arguments provided
Usage: ./check-args.sh <name>

$ ./check-args.sh Alice
Hello, Alice!

🔹 Looping Through Arguments

Using a for loop with "$@" processes each command-line argument individually. The syntax for arg in "$@"; do ... done iterates over all provided arguments, regardless of count. This is perfect for scripts designed to handle multiple files (e.g., a batch image converter or log parser) where the same operation needs to be applied to each input item. It makes scripts highly flexible and user-friendly for variable workloads.

#!/bin/bash
# loop-args.sh
echo "Processing $# arguments:"

for arg in "$@"; do
    echo "  - $arg"
done

Usage & Output:

$ ./loop-args.sh file1.txt file2.txt file3.txt
Processing 3 arguments:
- file1.txt
- file2.txt
- file3.txt

🔹 Using Shift Command

The shift command processes arguments sequentially by removing $1 and shifting the rest down. In a while [ $# -gt 0 ] loop, you can examine $1, process it, then call shift to move to the next. This is particularly useful for parsing command-line options followed by values, or when you need to handle the first few arguments differently before processing the remainder as a list.

#!/bin/bash
# shift-demo.sh
echo "First argument: $1"
shift
echo "After shift, first argument: $1"
echo "Remaining arguments: $@"

Usage & Output:

$ ./shift-demo.sh one two three
First argument: one
After shift, first argument: two
Remaining arguments: two three

🔹 Default Values

Parameter expansion provides elegant syntax for assigning default values when arguments are missing. Use ${1:-default} to use "default" if $1 is unset or empty. The related ${1:=default} also assigns the value to the variable. This technique makes scripts more robust and user-friendly by ensuring they have sensible values to work with, preventing errors from empty variables while allowing users to override defaults when needed.

#!/bin/bash
# defaults.sh
NAME=${1:-"Guest"}
AGE=${2:-"Unknown"}

echo "Name: $NAME"
echo "Age: $AGE"

Usage & Output:

$ ./defaults.sh
Name: Guest
Age: Unknown

$ ./defaults.sh Bob 25
Name: Bob
Age: 25

🧠 Test Your Knowledge

Which variable contains the number of arguments passed to a script?