Originally published on 2010-12-10; fully revised and updated.
This reference is for DevOps engineers writing Bash automation. You will learn how positional and special parameters work, how argument expansion differs between $* and $@, and how to handle script inputs safely. For historical context, see the original post.

Bash parameter types at a glance
In Bash, a parameter is any entity that stores a value. For day-to-day scripting, the most important categories are positional parameters (arguments passed to a script) and special parameters (shell-provided values such as exit code and process IDs).
- Positional parameters:
$0,$1…$9, and${10}onward. - Special parameters:
$#,$@,$*,$?,$$,$!,$-,$_. - Important: for argument numbers above 9, use braces (for example,
${10}), not$10.
Quick reference for common Bash parameters
| Parameter | What it represents | Typical use |
|---|---|---|
$0 | Script name as invoked (may include a path) | Usage/help messages |
$1 … $9, ${10} | Positional arguments | Read user input values |
$# | Argument count | Validate required inputs |
$* | All positional parameters | Aggregate argument handling |
$@ | All positional parameters | Forward arguments safely |
$? | Exit status of last command | Error handling branches |
$$ | Current shell process ID | Logging and process correlation |
$! | PID of most recent background job | Wait/monitor background work |
$- | Current shell option flags | Debugging shell mode state |
$_ | Last argument of previous command (context-dependent) | Occasional debugging |
How parameters flow through a script
A typical argument-handling flow validates count first, then processes inputs, and finally checks command status or background job IDs as needed.
flowchart TD
A[Run script with arguments] --> B[Shell assigns script name and positional values]
B --> C[Read argument count]
C --> D{Enough arguments}
D -- no --> E[Print usage and exit]
D -- yes --> F[Process positional parameters]
F --> G[Optional set -- to replace values]
G --> H[Run commands and check exit status]
H --> I[Optionally read process ids]
Example 1: Positional parameters for arithmetic input
This Bash script accepts two integer arguments, validates them, and performs arithmetic. Bash arithmetic uses integer math here, so division is integer division.
#!/usr/bin/env bash
if [ "$#" -lt 2 ]; then
echo "Usage: $0 num1 num2"
exit 1
fi
a=$1
b=$2
if [ "$b" -eq 0 ]; then
echo "Error: num2 must not be zero for division"
exit 1
fi
printf '$1=%s\n' "$a"
printf '$2=%s\n' "$b"
echo "Addition=$((a + b))"
echo "Subtraction=$((a - b))"
echo "Multiplication=$((a * b))"
echo "Division=$((a / b))"Code language: PHP (php)
chmod +x arithmetic.sh
./arithmetic.sh 12 10
$1=12
$2=10
Addition=22
Subtraction=2
Multiplication=120
Division=1
Example 2: Set, replace, and clear positional parameters with set —
The set builtin can overwrite positional parameters inside the current shell context. Using set -- with no following values clears them.
#!/usr/bin/env bash
printf 'Initial: $1=%s $2=%s $3=%s\n' "$1" "$2" "$3"
set -- First Second Third
printf 'After set words: $1=%s $2=%s $3=%s\n' "$1" "$2" "$3"
set -- -f -s -t
printf 'After set -- with hyphen values: $1=%s $2=%s $3=%s\n' "$1" "$2" "$3"
set --
printf 'After clear: $1=%s $2=%s $3=%s\n' "$1" "$2" "$3"Code language: PHP (php)
./positional.sh 12 10
Initial: $1=12 $2=10 $3=
After set words: $1=First $2=Second $3=Third
After set -- with hyphen values: $1=-f $2=-s $3=-t
After clear: $1= $2= $3=Code language: JavaScript (javascript)
Example 3: The difference between “$*” and “$@”
The most important difference appears in quoted form. Quoted "$*" becomes a single word, while quoted "$@" preserves each argument as a separate word.
| Form | Behavior | When to use |
|---|---|---|
"$*" | One string containing all arguments, joined by first character of IFS | When you intentionally need one combined value |
"$@" | Each argument remains a separate word | Preferred for forwarding arguments to another command |
$* (unquoted) | Subject to word splitting and pathname expansion | Usually avoid in robust scripts |
$@ (unquoted) | Also subject to splitting/expansion | Usually avoid in robust scripts |
#!/usr/bin/env bash
IFS='-'
cnt=1
echo 'Values of "$*":'
for arg in "$*"; do
echo "Arg #$cnt = $arg"
((cnt+=1))
done
cnt=1
echo 'Values of "$@":'
for arg in "$@"; do
echo "Arg #$cnt = $arg"
((cnt+=1))
doneCode language: PHP (php)
./expan.sh "This is" 2 3
Values of "$*":
Arg #1 = This is-2-3
Values of "$@":
Arg #1 = This is
Arg #2 = 2
Arg #3 = 3Code language: PHP (php)
Process and status parameters: $$, $!, $?, $-, $_
These special parameters are useful for process control and troubleshooting in automation scripts.
$$: PID of the current shell process.$!: PID of the most recently started background process.$?: exit code of the previous command.$-: currently enabled shell option flags.$_: last argument of the previous command; useful sometimes, but context-sensitive.
#!/usr/bin/env bash
echo "Shell PID: $$"
sleep 30 &
bg_pid=$!
echo "Most recent background PID: $bg_pid"
wait "$bg_pid"
echo "Exit status of wait: $?"
echo "Shell option flags: $-"
echo "alpha beta gamma"
echo "Previous command last argument via $_: $_"Code language: PHP (php)
Common pitfalls and best practices
- Validate argument count early with
$#and fail fast with a clear usage message. - Use
"$@"when forwarding arguments; avoid unquoted$*and$@in production scripts. - Use
${10},${11}, and so on for argument numbers above 9. - Guard arithmetic operations (especially division) with input checks.
- Use
set --intentionally; it replaces the current positional parameters in the active shell context. - Treat
$_as convenience, not core control logic, because behavior can vary by context.
If you consistently combine argument validation, careful quoting, and exit-status checks, your shell scripts become much safer for CI/CD and operations automation.
I’m Rajesh Kumar, a DevOps, SRE, DevSecOps, Cloud, and Platform Engineering expert passionate about sharing practical knowledge, real-world experiences, and industry best practices. I have worked at Cotocus and regularly write about technology, travel, investing, health, product reviews, and digital marketing through my various platforms.
I publish technical articles at DevOps School, travel stories at Holiday Landmark, stock market insights at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow, and SEO and digital marketing strategies at Wizbrand.
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services — all in one place.
Explore Hospitals