Bash script arguments explained banner
Bash focus guide

Bash Script Arguments Explained

Bash arguments are values you pass to a script when you run it. They let one script work with different files, services, directories or domains without editing the script each time.

On this page
Basics

What are Bash script arguments?

Arguments are extra values you add after the script name.

./check-file.sh /etc/passwd

Inside the script, /etc/passwd becomes $1, because it is the first argument.

#!/usr/bin/env bash

echo "First argument: $1"
$ ./args-demo.sh /etc/passwd
First argument: /etc/passwd
Reference

$0, $1, $2, $#, $@ explained

VariableMeaningExample
$0The script name./show-args.sh
$1The first argumentfile.txt
$2The second argumentnginx
$#The number of arguments2
$@All arguments"$@" preserves each argument safely
#!/usr/bin/env bash

echo "Script name: $0"
echo "First argument: $1"
echo "Second argument: $2"
echo "Number of arguments: $#"
$ ./show-args.sh apple banana
Script name: ./show-args.sh
First argument: apple
Second argument: banana
Number of arguments: 2
Cleaner scripts

Store arguments in named variables

$1 and $2 are useful, but named variables make scripts easier to read.

FILE="$1"
SERVICE="$2"

echo "File: $FILE"
echo "Service: $SERVICE"

This is easier to understand later than using $1 and $2 everywhere.

Validation

Check if an argument was provided

Good scripts check their input before doing anything important.

FILE="${1:-}"

if [ -z "$FILE" ]; then
  echo "Usage: $0 file"
  exit 1
fi

${1:-} means “use the first argument if it exists, otherwise use an empty value”. This avoids errors if you later use set -u.

$ ./check-file.sh
Usage: ./check-file.sh file
All arguments

Loop through all arguments with "$@"

Use quoted "$@" when you want to process every argument safely.

#!/usr/bin/env bash

for item in "$@"; do
  echo "Argument: $item"
done
$ ./show-all.sh one two "three words"
Argument: one
Argument: two
Argument: three words
Use "$@", not plain $@. The quoted version preserves arguments with spaces.
Quoting

Handling arguments with spaces

If an argument contains spaces, quote it when running the script and quote it inside the script.

./check-file.sh "my file.txt"
FILE="$1"

if [ -f "$FILE" ]; then
  echo "File exists: $FILE"
fi

Without quotes, Bash may treat one filename as multiple separate words.

Practical scripts

Example script: check if a file exists

#!/usr/bin/env bash

FILE="${1:-}"

if [ -z "$FILE" ]; then
  echo "Usage: $0 file"
  exit 1
fi

if [ -f "$FILE" ]; then
  echo "[OK] File exists: $FILE"
  exit 0
else
  echo "[WARN] File not found: $FILE"
  exit 1
fi
$ ./check-file-arg.sh /etc/passwd
[OK] File exists: /etc/passwd

Example script: check a service name passed as an argument

#!/usr/bin/env bash

SERVICE="${1:-}"

if [ -z "$SERVICE" ]; then
  echo "Usage: $0 service-name"
  exit 1
fi

if systemctl is-active --quiet "$SERVICE"; then
  echo "[OK] $SERVICE is running"
else
  echo "[WARN] $SERVICE is not running"
  exit 1
fi
$ ./check-service-arg.sh sshd
[OK] sshd is running

Example script: dry-run backup using two arguments

#!/usr/bin/env bash

SOURCE="${1:-}"
DEST="${2:-}"

if [ -z "$SOURCE" ] || [ -z "$DEST" ]; then
  echo "Usage: $0 source-dir destination-dir"
  exit 1
fi

if [ ! -d "$SOURCE" ]; then
  echo "[ERROR] Source directory not found: $SOURCE"
  exit 1
fi

mkdir -p "$DEST"
rsync -av --dry-run "$SOURCE"/ "$DEST"/
$ ./backup-dir-arg.sh ./site ./backup
sending incremental file list
index.html
styles.css
images/logo.png

sent 219 bytes  received 27 bytes  492.00 bytes/sec
total size is 14,122  speedup is 57.41
Dry run complete. Remove --dry-run only after checking the output.

For more backup ideas, see Automate Linux Backups Using rsync and systemd.

Downloads

Download the example scripts

Mistakes

Common Bash argument mistakes

MistakeProblemBetter
FILE=$1Can break with spaces or empty values.FILE="${1:-}"
for item in $@Splits arguments with spaces.for item in "$@"
No usage checkThe script fails unclearly when input is missing.Print Usage: $0 file and exit.
Using $1 everywhereHarder to read and maintain.Use named variables like FILE="$1".
Related

Keep learning Bash

Reusable pattern

A solid argument-checking pattern

Most admin scripts should validate arguments before doing any work. This avoids half-running a script with the wrong target.

#!/usr/bin/env bash

usage() {
  echo "Usage: $0 DOMAIN LOGFILE"
  echo "Example: $0 example.com /var/log/httpd/access_log"
}

if [ "$#" -ne 2 ]; then
  usage
  exit 1
fi

domain="$1"
logfile="$2"

if [ ! -f "$logfile" ]; then
  echo "ERROR: logfile not found: $logfile"
  exit 2
fi

echo "Checking $domain in $logfile"
Example output:
$ ./check-domain.sh
Usage: ./check-domain.sh DOMAIN LOGFILE
Example: ./check-domain.sh example.com /var/log/httpd/access_log

$ ./check-domain.sh example.com missing.log
ERROR: logfile not found: missing.log
FAQ

Frequently Asked Questions

What does $1 mean in Bash?

$1 is the first positional argument passed to the script or function.

What does $# mean in Bash?

$# is the number of positional arguments passed to the script or function.

What is the difference between $@ and $*?

$@ preserves each argument as a separate value when quoted, which is usually safer for loops and forwarding arguments.

How do I check if a Bash argument is missing?

Check the argument count with $# or test a specific variable with -z, for example [ -z "$1" ].

$ practise_next --topic bash

Practise this next

Turn the guide into practice with a related quiz, builder, cheat sheet or learning path.