In Bash, variables store data that can be referenced and manipulated throughout a script or command-line session. A variable is essentially a named placeholder for information such as strings, numbers, or command output.
The following line defines a variable named VAR_NAME and assigns it a value:
VAR_NAME="Hello"There must be no spaces around the = sign:
VAR_NAME = "Hello" # Syntax errorVariable names are case-sensitive in Bash:
VAR="hello"
var="world"
echo $VAR # Output: hello
echo $var # Output: worldHere, VAR and var are two distinct variables.
Naming rules:
- Names can contain letters, numbers, and underscores (
_). - Names must start with a letter or an underscore — not a number.
- Special characters such as
-,@,$,!,*,#,&,=, and?cannot be used in variable names.
Examples of invalid variable names:
# Starting with a number
1var="Hello"
# Containing special characters
var-name="Hello"
var@name="Hello"
var$name="Hello"
# Containing a space
var name="Hello"
# Using reserved characters
var*name="Hello"
var#name="Hello"Note: Bash keywords such as
for,if, andwhilecan technically be used as variable names in simple assignments (e.g.,for="Hello"is valid syntax). However, doing so is strongly discouraged because it creates confusing, hard-to-maintain code.
To retrieve a variable's value, prefix its name with a dollar sign ($):
name="Alice"
echo $name # Output: AliceVariables are expanded inside double-quoted strings but not inside single-quoted strings:
name="Bob"
echo "Hello, $name!" # Output: Hello, Bob!
echo 'Hello, $name!' # Output: Hello, $name! (no variable expansion)To concatenate a variable with adjacent text, use curly braces {} to delimit the variable name:
fruit="apple"
echo "I like ${fruit}s" # Output: I like applesWithout curly braces, Bash looks for a variable named fruits, which does not exist:
fruit="apple"
echo "I like $fruits" # Output: I likeTo append text to an existing variable:
STR="first string"
STR=${STR}:end
echo $STR # Output: first string:endTo prepend text to an existing variable:
STR="first string"
STR=start:${STR}
echo $STR # Output: start:first stringIn Bash, all variables are treated as strings by default. Consider the following example:
num=10
num=num+5
echo $num # Output: num+5The value 10 is stored as a string. The second assignment does not perform arithmetic — Bash treats num+5 as a literal string.
Bash provides several ways to perform arithmetic:
- Arithmetic expansion:
$(( )) - Arithmetic evaluation:
(( )) - The
letcommand - The
exprcommand
Using $(( ))
Arithmetic expansion evaluates an expression and returns the result:
num=10
num=$((num + 5)) # Not to be confused with command substitution: $( ... )
echo $num # Output: 15Using (( ))
Arithmetic evaluation performs calculations without the $ prefix:
num=10
((num = num + 5))
echo $num # Output: 15Using let
The let command evaluates arithmetic expressions:
num=10
let num=num+5
echo $num # Output: 15Using expr
The expr command is an external utility. Operators and operands must be separated by spaces:
num=10
num=$(expr $num + 5)
echo $num # Output: 15Bash does not natively support floating-point arithmetic. For decimal calculations, use external tools such as bc or awk:
num1=3.5
num2=1.2
result=$(echo "$num1 + $num2" | bc)
echo $result # Output: 4.7You can explicitly declare a variable as an integer using declare -i. Bash then performs arithmetic on assignments automatically:
declare -i num=10
num=num+5
echo $num # Output: 15Assigning a non-numeric value to an integer variable sets it to 0:
declare -i num
num="abc"
echo $num # Output: 0If the assigned string begins with digits, Bash uses the numeric prefix and ignores the rest:
declare -i num
num="123abc"
echo $num # Output: 123An undefined variable is one that has never been assigned a value. Referencing it expands to an empty string:
echo "$undefined_var" # Output: (nothing)You can test whether a variable is defined using the -v test (Bash 4.2+):
if [ -v undefined_var ]; then
echo "Variable exists"
else
echo "Variable is undefined" # This will print
fiThe unset command removes a variable, making it undefined:
myvar="hello"
echo $myvar # Output: hello
unset myvar
echo $myvar # Output: (nothing)unset does not produce an error if the variable does not exist:
unset nonexistent_var # No errorA variable can be explicitly defined with an empty value:
var=
echo "$var" # Output: (nothing)This is useful when you need to ensure a variable exists but has no initial value.
You can test for an empty (or undefined) variable using -z:
var=
if [ -z "$var" ]; then
echo "Variable is empty or undefined"
else
echo "Variable is not empty"
fiA readonly variable cannot be changed or unset after it has been declared. It is used to define constants that must remain fixed throughout a script's execution.
To declare a readonly variable:
readonly VAR_NAME=valueAlternatively, use the declare command:
declare -r VAR_NAME=valueAttempting to modify a readonly variable produces an error:
#!/bin/bash
readonly PI=3.14159
echo "The value of PI is $PI"
PI=3.14 # Error: PI: readonly variableEverything discussed so far — defining, naming, referencing, and modifying variables — applies to local shell variables: variables that exist only in the current shell session and are not visible to child processes.
However, Bash supports several other types of variables as well, each with a different scope and purpose:
| Type | Example | Description |
|---|---|---|
| Local shell variable | MY_VAR="Hello!" |
Exists only in the current shell. |
| Environment variable | export ENV_VAR="World!" |
Passed to child processes (inherited). |
| Built-in shell variable | $BASH_VERSION |
Managed by Bash internally. |
| Special shell variable | $?, $$, $!, $@ |
Represent shell state or metadata. |
- A local variable is defined in the current shell session. It is not passed to child processes or subshells.
- An environment variable is exported to child processes and subshells using the
exportcommand. - A built-in variable is predefined by the shell to store information about its own state or behavior.
- A special variable is a reserved, read-only variable that the shell maintains automatically. It may be referenced but not assigned to.
Each type is covered in its own section: Environment Variables, Built-in Shell Variables, and Special Variables.
To display all shell variables and functions:
declare
The -p flag displays variable declarations along with their attributes and values:
declare -p
To display only environment variables:
printenv