Special Variables — $0, $#, $@, $?, and More
Bash provides a set of read-only special variables that give you runtime information: script name, arguments, last exit code, process ID, and more.
Bash automatically sets a collection of special read-only variables. These give you information about the running script, its arguments, the exit status of the last command, and the current process. Knowing them is essential for writing robust scripts.
Positional Parameters — Script Arguments
Positional parameter quick reference
| Variable | Meaning |
|---|---|
$0 | Script name (or function name inside a function) |
$1 … $9 | First through ninth argument |
${10} | Tenth argument (braces required for double digits) |
$# | Number of arguments |
$@ | All arguments as separate quoted words — use in loops |
$* | All arguments as a single string — rarely the right choice |
#!/usr/bin/env bash
echo "Script name: $0"
echo "Argument 1: $1"
echo "Argument 2: $2"
echo "Total args: $#"
echo ""
echo "All args with $@:"
for arg in "$@"; do
echo " -> $arg"
done./show-args.sh hello "world foo" bar
# Script name: ./show-args.sh
# Argument 1: hello
# Argument 2: world foo
# Total args: 3
# All args:
# -> hello
# -> world foo
# -> bar$@ vs $*
Always use "$@" (quoted) when you want to pass arguments to another command or loop over them. With "$@", each argument stays as a separate word, even with spaces inside.
"$*" joins all arguments into one string separated by the value of $IFS (usually space). This loses the individual argument boundaries.
Exit Status — $?
Every command exits with a status code: 0 means success, anything else is failure. $? holds the exit code of the most recently executed command.
ls /tmp
echo "Exit code: $?" # 0 — success
ls /nonexistent
echo "Exit code: $?" # 2 — failure (no such file)
grep "something" file.txt
echo "Exit code: $?" # 0 if found, 1 if not found, 2 if errorProcess and Shell Variables
Other special variables
| Variable | Meaning |
|---|---|
$$ | PID (Process ID) of the current shell |
$! | PID of the last background process (&) |
$- | Current shell options (e.g. himBH) |
$LINENO | Current line number in the script |
$BASH_VERSION | Version of Bash running |
$RANDOM | Random integer 0–32767 (re-evaluated each time) |
$SECONDS | Seconds since the script started |
echo "My PID: $$"
echo "A random number: $RANDOM"
echo "Another random: $RANDOM" # different each time
sleep 2
echo "Script has been running $SECONDS seconds"
# Using $$ to create unique temp files
tmpfile="/tmp/myscript-$$.tmp"
echo "data" > "$tmpfile"
# cleanup:
rm "$tmpfile"A script is called with `./script.sh one two three`. What does `$#` contain?
Write a script require-args.sh that:
- Requires exactly 2 arguments — if not, prints "Usage: require-args.sh <name> <age>" and exits with code 1
- If correct, prints "Name: Alice, Age: 30" (substituting the actual arguments)