Command Line Arguments
Command line arguments allow users to pass data to your scripts when they run them. This makes scripts flexible and reusable.
What Are Command Line Arguments?
When you run a script with additional words after the script name, those become arguments:
./greet.sh Alice Bob Carol
# $1 $2 $3
Each word becomes a positional parameter accessible inside the script.
Accessing Arguments
Inside your script, use $1, $2, etc. to access arguments:
#!/bin/bash
# greet.sh - Greet users by name
echo "Hello, $1!"
echo "And hello to $2 as well!"
echo "Don't forget about $3!"
Run it:
./greet.sh Alice Bob Carol
# Output:
# Hello, Alice!
# And hello to Bob as well!
# Don't forget about Carol!
Checking Argument Count
Always verify you have the required arguments:
#!/bin/bash
# Require exactly 2 arguments
if [ $# -ne 2 ]; then
echo "Usage: $0 <source> <destination>"
exit 1
fi
SOURCE=$1
DEST=$2
echo "Copying from $SOURCE to $DEST"
Exercise: Create Script with Arguments
Access command line arguments:
Arguments with Spaces
Arguments with spaces need quoting when calling the script:
#!/bin/bash
# greet.sh
echo "Hello, $1!"
# Calling the script:
./greet.sh John Smith # $1="John", $2="Smith"
./greet.sh "John Smith" # $1="John Smith"
Inside your script, always quote variables:
#!/bin/bash
FILENAME="$1"
cat "$FILENAME" # Correct - handles spaces
cat $FILENAME # Wrong - breaks on spaces
Processing All Arguments
Use $@ to work with all arguments:
#!/bin/bash
# process_files.sh - Process multiple files
echo "Processing $# files..."
for file in "$@"; do
echo "Processing: $file"
# do something with $file
done
The shift Command
shift removes the first argument and shifts others down:
#!/bin/bash
# shift_demo.sh
echo "Before shift:"
echo " \$1 = $1"
echo " \$2 = $2"
echo " \$# = $#"
shift
echo "After shift:"
echo " \$1 = $1" # Was $2
echo " \$2 = $2" # Was $3
echo " \$# = $#" # Decreased by 1
Using shift in Loops
#!/bin/bash
# Process arguments one at a time
while [ $# -gt 0 ]; do
echo "Processing: $1"
shift
done
Default Argument Values
Provide defaults when arguments are missing:
#!/bin/bash
# greet.sh with default
NAME="${1:-World}"
echo "Hello, $NAME!"
# ./greet.sh -> Hello, World!
# ./greet.sh Alice -> Hello, Alice!
More default value patterns:
# ${var:-default} - Use default if var is unset or empty
NAME="${1:-Guest}"
# ${var:=default} - Set var to default if unset or empty
NAME="${1:=Guest}"
# ${var:?error} - Show error and exit if unset
NAME="${1:?'Name is required'}"
Parsing Named Options
For more complex scripts, use getopts:
#!/bin/bash
# Uses: ./script.sh -n Alice -a 25
while getopts "n:a:" opt; do
case $opt in
n) NAME="$OPTARG" ;;
a) AGE="$OPTARG" ;;
?) echo "Usage: $0 -n name -a age" ;;
esac
done
echo "Name: $NAME, Age: $AGE"
The colon after an option letter means it requires an argument.
Long Options with getopt
For GNU-style long options, use getopt:
#!/bin/bash
# Uses: ./script.sh --name Alice --age 25
OPTS=$(getopt -o n:a: --long name:,age: -- "$@")
eval set -- "$OPTS"
while true; do
case "$1" in
-n|--name) NAME="$2"; shift 2 ;;
-a|--age) AGE="$2"; shift 2 ;;
--) shift; break ;;
esac
done
echo "Name: $NAME, Age: $AGE"
Exercise: Script with Default
Use default argument value:
Best Practices
- Always check argument count before using them
- Quote all variables that could contain spaces
- Provide usage messages when arguments are wrong
- Use default values for optional arguments
- Document expected arguments in comments
#!/bin/bash
# backup.sh - Backup files to destination
# Usage: backup.sh <source> <dest> [options]
# source - Directory to backup
# dest - Backup destination
# -v - Verbose mode
if [ $# -lt 2 ]; then
echo "Usage: $0 <source> <dest> [-v]"
exit 1
fi
SOURCE="$1"
DEST="$2"
VERBOSE="${3:-}"
# ... rest of script
Key Takeaways
- Arguments are accessed with
$1,$2, etc. $#contains the total number of arguments$@contains all arguments (use with quotes)shiftremoves the first argument- Use
${1:-default}for default values - Always quote variables:
"$1"not$1 getoptsparses short options like-f- Check argument count and provide usage messages

