Special Variables
Bash provides special variables for accessing script arguments, process information, exit status, and more. These are variables you will use frequently when writing shell scripts.
Syntax
Display the script name.
echo $0
Display positional parameters (arguments).
echo $1 $2 $3
Reference all arguments.
echo "$@" # Treats each argument as a separate string echo "$*" # Treats all arguments as a single string
Display the number of arguments.
echo $#
Display the exit status of the last command.
echo $?
Display the PID of the current shell.
echo $$
Display the PID of the last process run in the background.
echo $!
Special Variables
| Variable | Description |
|---|---|
| $0 | The filename of the script (or the shell name). |
| $1 〜 $9 | The 1st through 9th arguments passed to the script. |
| ${10} and beyond | Arguments from the 10th onward require curly braces. |
| $@ | Expands all arguments as separate strings (can be safely quoted with double quotes). |
| $* | Expands all arguments as a single string, separated by IFS. |
| $# | The number of arguments passed. |
| $? | The exit status of the last command (0 = success, 1 or more = failure). |
| $$ | The PID of the current shell process. |
| $! | The PID of the last process run in the background. |
| $_ | The last argument of the previous command. |
| $LINENO | The line number currently being executed. Useful for debugging. |
| $FUNCNAME | An array of the currently executing function names. |
| $RANDOM | Returns a random integer between 0 and 32767 each time it is referenced. |
| $SECONDS | The number of seconds elapsed since the script started. |
Sample Code
Save the following script as script.sh and run it with $ ./script.sh Hello World 3.
This script reads the arguments passed to it.
script.sh
#!/bin/bash
echo "Script name: $0"
echo "1st argument: $1"
echo "2nd argument: $2"
echo "Number of arguments: $#"
echo "All arguments: $@"
bash script.sh Hello World 3
Script name: script.sh
1st argument: Hello
2nd argument: World
Number of arguments: 3
All arguments: Hello World 3
Print an error message and exit when required arguments are missing.
check_args.sh
if [ $# -lt 2 ]; then
echo "Usage: $0 arg1 arg2" >&2
exit 1
fi
bash check_args.sh one
Usage: check_args.sh arg1 arg2
Use $? to check the exit status of the previous command. 0 means success; 1 or greater means failure.
exit_status.sh
ls /nonexistent 2>/dev/null
echo "ls exit status: $?"
ls /tmp 2>/dev/null
echo "ls exit status: $?"
bash exit_status.sh
ls exit status: 2
ls exit status: 0
Use $$ to get the PID of the current shell, and $! to get the PID of a background process.
pid.sh
echo "Current PID: $$"
sleep 10 &
echo "Background PID: $!"
bash pid.sh
Current PID: 12345
Background PID: 12346
$RANDOM returns a random integer between 0 and 32767 each time it is referenced.
echo "Random: $RANDOM" Random: 27483
The difference between "$@" and "$*" becomes clear when arguments contain spaces.
at_vs_star.sh
args=("hello world" "foo")
for a in "${args[@]}"; do echo "[$a]"; done
for a in "${args[*]}"; do echo "[$a]"; done
bash at_vs_star.sh
[hello world]
[foo]
[hello world foo]
Notes
$? is essential for checking whether the previous command succeeded. However, it is immediately overwritten after being read, so save it to another variable first for safe use (e.g., ret=$?; if [ $ret -ne 0 ]; then ...).
Wrapping "$@" in double quotes safely handles arguments that contain spaces. Always use "$@" when passing script arguments directly to another command.
For how arguments work inside functions, see Function Arguments and Return Values.
If you find any errors or copyright issues, please contact us.