Skip to content

Variable

A variable is a label assigned to a location in computer memory that holds data.

  • Assignment: Do not use spaces around the = sign. Escape spaces in values with backslashes or quotes.

    var=value var2="one two three" var3=one\ two\ three

  • Referencing: Use $ or ${} to retrieve the value.Bash

    echo $var echo $\{var\}

  • Indirect Referencing: Dynamically reference a variable using the value of another.Bash

    var=value value=hello eval b=\$$var echo $b

Bash does not strictly segregate variables by type; they are treated as character strings by default. Arithmetic operations and comparisons are permitted depending on the context (e.g., if the value contains only digits).

  • Use declare or typeset (exact synonyms) to modify variable properties.Bash

    Terminal window
    $ n=6/3
    $ echo "n = $n"
    n = 6/3
    $ declare -i n
    $ n=6/3
    $ echo "n = $n"
    n = 2

Bash has built-in operators for manipulating strings.

SyntaxAction
${#var}Length of the variable. (For arrays, length of the first element).
${var:position:length}Extracts a substring of $length starting at $position (0-based indexing).
${var#Pattern}Removes the shortest match of $Pattern from the front (prefix).
${var##Pattern}Removes the longest match of $Pattern from the front (prefix).
${var%Pattern}Removes the shortest match of $Pattern from the back (suffix).
${var%%Pattern}Removes the longest match of $Pattern from the back (suffix).
${var/Pattern/Replacement}Replaces the first match of $Pattern with $Replacement (deletes if replacement is omitted).
${var//Pattern/Replacement}Replaces all matches of $Pattern with $Replacement.
${var/#Pattern/Replacement}Substitutes if the prefix matches $Pattern.
${var/%Pattern/Replacement}Substitutes if the suffix matches $Pattern.

String Manipulation Examples:

Terminal window
$ stringZ=abcABC123ABCabc
$ echo ${#stringZ}
15
$ arrayX=(a ab abc)
$ echo ${#arrayX}
1
$ stringZ=abcABC123ABCabc
$ echo ${stringZ:2:5}
cABC1
$ stringZ=abcABC123ABCabc
$ echo ${stringZ#a*C}
123ABCabc
$ echo ${stringZ##a*C}
abc
$ stringZ=abcABC123ABCabc
$ echo ${stringZ%a*c}
abcABC123ABC
$ echo ${stringZ%%b*c}
a
$ stringZ=abcABC123ABCabc
$ echo ${stringZ/abc/xyz}
xyzABC123ABCabc
$ echo ${stringZ//abc/xyz}
xyzABC123ABCxyz
$ stringZ=abcABC123ABCabc
$ echo ${stringZ/abc}
ABC123ABCabc
$ echo ${stringZ//abc}
ABC123ABC
$ stringZ=abcABC123ABCabc
$ echo ${stringZ/#abc/XYZ}
XYZABC123ABCabc
$ echo ${stringZ/%abc/XYZ}
abcABC123ABCXYZ

These operators handle unset, empty, or missing variables, establishing fallbacks or throwing errors. (Note: The inclusion of : makes the operator check if the variable is both set AND not null).

SyntaxAction
${var-default} / ${var:-default}Uses default if the variable is unset (or null if : is used).
${var=default} / ${var:=default}Sets the variable to default if unset (or null if : is used).
${var+alt} / ${var:+alt}Uses alt if the variable is set (or set and not null if : is used).
${var?err} / ${var:?err}Uses the variable if set; otherwise, prints err and aborts script (exit 1).

Substitution Examples:

Terminal window
$ var1=1
$ var2=2
$ echo ${var1-$var2}
1
$ echo ${var3-$var2}
2
$ var1=1
$ var3= # declared but null
$ echo ${var3-$var1}
$ echo ${var3:-$var1}
1
#!/bin/bash
DEFAULT_FILENAME=generic.data
# If not otherwise specified, the following command block operates on the
# file "generic.data".
filename=${1:-$DEFAULT_FILENAME}
...
Terminal window
$ varZ=
$ echo ${varZ=abc}
$ echo ${varZ:=abc}
abc
$ echo ${var=abc}
abc
$ echo ${var=xyz}
abc
Terminal window
# Example with undefined parameter for ${parameter+alt_value}
$ a=${param_undefined+xyz}
$ echo "a = $a"
a = # because param_undefined is not defined at all
# Example with empty parameter for ${parameter+alt_value}
$ param1=
$ a=${param1+xyz}
$ echo "a = $a"
a = xyz # because param1 is set, even if empty
# Example with empty parameter for ${parameter:+alt_value}
$ param2=
$ a=${param2:+xyz}
$ echo "a = $a"
a = # because param2 is set, but empty
# Example with parameter with value for ${parameter:+alt_value}
$ param3=123
$ a=${param3:+xyz}
$ echo "a = $a"
a = xyz # because param3 is set and not empty
#!/bin/bash
: ${HOSTNAME?} ${USER?} ${MAIL?}
echo "Name of the machine is $HOSTNAME."
echo "You are $USER."
echo "Your mail INBOX is located in $MAIL."
echo
echo "If you are reading this message,"
echo "critical environmental variables have been set."
echo

1. Local Variables

Visible only within a specific code block or function.

Terminal window
$ func() {
local var=$1
echo $var
}
$ echo $var
$ func Hello
Hello

2. Environment Variables

Affect shell and user interface behavior. Check current variables with the env command. They can be set:

  • System-wide: /etc/environment
  • For all sessions (user): ~/.bashrc, ~/.bash_profile
  • For current session: export MYVAR=value
  • During script execution: . ~/my_env_vars or source ~/my_env_vars
Terminal window
$ env
LC_ADDRESS=en_US.UTF-8
HOSTNAME=node1
LC_MONETARY=en_US.UTF-8
TERM=xterm-256color
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=10.0.2.2 37896 22
LC_NUMERIC=en_US.UTF-8
SSH_TTY=/dev/pts/0
USER=vagrant
...

3. Positional Parameters

Arguments passed from the command line.

  • $0: Name of the script.
  • $1 - $9: First through ninth arguments.
  • ${10}, ${11}: Arguments 10 and beyond require brackets.
  • $#: Total number of command-line arguments.
  • $* and $@: All positional parameters combined.
#!/bin/bash
NUMBER=1
for arg in $@; do
echo -e "argument #${NUMBER}: $arg";
((NUMBER++));
done
bash script.sh 1 apple hello 4
argument #1: 1
argument #2: apple
argument #3: hello
argument #4: 4

4. Built-in Variables

Special shell variables native to the interpreter.

An array holds multiple values. Any variable can be used as an array.

  • No maximum size limit.
  • Elements do not need to be indexed/assigned contiguously.
  • Zero-based: The first element is index 0.

Initialization & Access:

Terminal window
$ my_array=( zero one two three four five
$ my_array[6]=six
$ declare -a new_array
$ echo ${my_array[6]}
six
$ my_array=( zero one two three four five )
$ echo ${my_array[@]}
zero one two three four five six
$ echo ${my_array[*]}
zero one two three four five six
$ echo ${#my_array[@]}
7
$ echo ${#my_array[*]}
7

Here is the complete, structured summary of your notes. The raw examples have been consolidated into fully executable Bash scripts categorized by their logical function.

Variables are memory labels representing data. Bash treats variables as character strings by default, but permits arithmetic if the context and content strictly contain digits.

basics.sh

#!/bin/bash
# Assignment (No spaces around '=')
var1="value"
var2="one two three"
var3=one\ two\ three
# Referencing
echo "Direct: $var1 or ${var1}"
# Indirect Referencing (Evaluating a variable's value as a variable name)
value="hello"
eval indirect=\$$var1
echo "Indirect: $indirect"
# Variable Types (Typecasting)
n=6/3
echo "String context n = $n" # Outputs 6/3
declare -i n # Cast to integer
n=6/3
echo "Integer context n = $n" # Outputs 2

Bash possesses native, regex-like string parsing capabilities.

string_manipulation.sh

#!/bin/bash
stringZ="abcABC123ABCabc"
arrayX=(a ab abc)
echo "String Length: ${#stringZ}" # 15
echo "Array First Element Length: ${#arrayX}" # 1
echo "Substring (pos 2, len 5): ${stringZ:2:5}" # cABC1
# Prefix Removal (# = shortest, ## = longest)
echo "Remove shortest prefix 'a*C': ${stringZ#a*C}" # 123ABCabc
echo "Remove longest prefix 'a*C': ${stringZ##a*C}" # abc
# Suffix Removal (% = shortest, %% = longest)
echo "Remove shortest suffix 'a*c': ${stringZ%a*c}" # abcABC123ABC
echo "Remove longest suffix 'b*c': ${stringZ%%b*c}" # a
# Replacement (/ = first match, // = all matches)
echo "Replace first 'abc' with 'xyz': ${stringZ/abc/xyz}" # xyzABC123ABCabc
echo "Replace all 'abc' with 'xyz': ${stringZ//abc/xyz}" # xyzABC123ABCxyz
echo "Delete first 'abc': ${stringZ/abc}" # ABC123ABCabc
echo "Delete all 'abc': ${stringZ//abc}" # ABC123ABC
# Anchored Replacement (# = prefix, % = suffix)
echo "Replace prefix 'abc': ${stringZ/#abc/XYZ}" # XYZABC123ABCabc
echo "Replace suffix 'abc': ${stringZ/%abc/XYZ}" # abcABC123ABCXYZ

Used to handle undefined or null variables securely, establishing fallback defaults or error triggers.

(Note: Using : handles both unset and null variables. Omitting : handles only unset variables).

param_substitution.sh

#!/bin/bash
var1=1
var2=2
var3="" # Declared but null
param_undef=
# Default Values (Use default if unset/null)
echo "Use default (-): ${var_unset-$var2}" # 2
echo "Use default (:-): ${var3:-$var1}" # 1 (Because var3 is null)
# Assign Default Values (Set variable to default if unset/null)
echo "Assign default (=): ${varZ=abc}" # abc
echo "Assign default (:=): ${varZ:=xyz}" # abc (Already set to abc above)
# Alternative Values (Use alternative IF variable IS set)
# + triggers if set (even if null). :+ triggers ONLY if set AND not null.
echo "Alt (+): ${param_undef+xyz}" # (Empty, because undef)
echo "Alt (+): ${var3+xyz}" # xyz (Because var3 is set to null)
echo "Alt (:+): ${var3:+xyz}" # (Empty, because var3 is null)
echo "Alt (:+): ${var1:+xyz}" # xyz (Because var1 has a value)
# Error Handling (Abort script if unset/null)
# Will exit with status 1 if HOSTNAME, USER, or MAIL are empty/unset.
: ${HOSTNAME?} ${USER?} ${MAIL?}
echo "Critical variables are set. Name: $HOSTNAME, User: $USER"

4. Variable Scopes & Positional Parameters

Section titled “4. Variable Scopes & Positional Parameters”

Variables exist in specific scopes: Local (function-level), Global (script-level), Environment (OS-level), and Positional (CLI arguments).

scopes_and_args.sh

#!/bin/bash
# Local Scope
func() {
local func_var=$1
echo "Inside function: $func_var"
}
func "Hello"
echo "Outside function (should be empty): $func_var"
# Environment Variables (Affect shell behavior)
# Set via: /etc/environment, ~/.bashrc, or export MYVAR=value
echo "Current User Env: $USER"
# Positional Parameters ($0 is script name, $1-$9 are args, ${10} for 10+)
echo "Total arguments passed (\$#): $#"
NUMBER=1
# $@ and $* represent ALL positional arguments
for arg in "$@"; do
echo "Argument #${NUMBER}: $arg"
((NUMBER++))
done
# Run this script with: ./scopes_and_args.sh 1 apple hello 4

Zero-indexed structures holding multiple values. They lack size limits and do not require contiguous assignment.

arrays.sh

#!/bin/bash
declare -a my_array # Explicit declaration (optional)
# Initialization
my_array=(zero one two three four five)
my_array[6]="six" # Non-contiguous assignment is allowed
# Dereferencing
echo "Element 6: ${my_array[6]}"
# Fetch All Elements (@ or *)
echo "All elements (@): ${my_array[@]}"
echo "All elements (*): ${my_array[*]}"
# Array Length (#)
echo "Total elements: ${#my_array[@]}" # 7