Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Linux & Mac & Bash Command Dictionary

  1. Home
  2. Linux & Mac & Bash Command Dictionary
  3. Special Variables

Special Variables

Since: All Linux
macOS(2001 Cheetah)
Bash 1.0(1989)

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

VariableDescription
$0The filename of the script (or the shell name).
$1 〜 $9The 1st through 9th arguments passed to the script.
${10} and beyondArguments 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.
$LINENOThe line number currently being executed. Useful for debugging.
$FUNCNAMEAn array of the currently executing function names.
$RANDOMReturns a random integer between 0 and 32767 each time it is referenced.
$SECONDSThe 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.

sample_script.sh
#!/bin/bash
echo "Script name: $0"
echo "1st argument: $1"
echo "2nd argument: $2"
echo "Number of arguments: $#"
echo "All arguments: $@"

The following example demonstrates this:

bash script.sh Ayanami Rei 3
Script name: script.sh
1st argument: Ayanami
2nd argument: Rei
Number of arguments: 3
All arguments: Ayanami Rei 3

Print an error message and exit when required arguments are missing.

sample_check_args.sh
if [ $# -lt 2 ]; then
    echo "Usage: $0 arg1 arg2" >&2
    exit 1
fi

Run the following command:

bash check_args.sh Shinji
Usage: check_args.sh arg1 arg2

Use $? to check the exit status of the previous command. 0 means success; 1 or greater means failure.

sample_exit_status.sh
ls /nonexistent 2>/dev/null
echo "ls exit status: $?"

ls /tmp > /dev/null 2>&1
echo "ls exit status: $?"

Run the following command:

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.

sample_pid.sh
echo "Current PID: $$"

sleep 10 &
echo "Background PID: $!"

Run the following command:

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.

sample_at_vs_star.sh
args=("Ayanami Rei" "Ikari Shinji")
for a in "${args[@]}"; do echo "[$a]"; done
for a in "${args[*]}"; do echo "[$a]"; done

Run the following command:

bash at_vs_star.sh
[Ayanami Rei]
[Ikari Shinji]
[Ayanami Rei Ikari Shinji]

Common Mistakes

Common Mistake 1: $? is overwritten before it is checked

$? holds the exit status of the most recent command, but it is overwritten by every subsequent command — including echo. Read it immediately or save it to a variable before using it.

ls /nonexistent 2>/dev/null
echo "doing something else"
echo "exit status: $?"
exit status: 0
($? reflects echo's status, not ls's)

Save the exit status to a variable before anything else.

ls /nonexistent 2>/dev/null
ret=$?
echo "exit status: $ret"
exit status: 2

Common Mistake 2: Using $* instead of $@ loses argument boundaries

"$*" joins all arguments into a single string. When arguments contain spaces, they are merged together and their boundaries are lost. Use "$@" to keep each argument separate.

sample_at_vs_star_mistake.sh
show_args() {
    echo "--- using \$*"
    for a in "$*"; do echo "  [$a]"; done
    echo "--- using \$@"
    for a in "$@"; do echo "  [$a]"; done
}
show_args "Ayanami Rei" "Ikari Shinji"

Run the following command:

bash at_vs_star_mistake.sh
--- using $*
  [Ayanami Rei Ikari Shinji]
--- using $@
  [Ayanami Rei]
  [Ikari Shinji]

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 .