Skip to content

02. Variables

What is a variable?

A variable is a name that stores a value (string, number, filename, etc.). In Bash you assign with = (no spaces around =) and reference with a leading $.


Basic variable assignment & use

#!/bin/bash
STRING="HELLO WORLD!!!"   # assign
echo $STRING              # reference

Run:

$ ./hello_world.sh
HELLO WORLD!!!

Tip: Quoting values preserves spaces and special characters:

NAME="Subrat Samantaray"
echo "$NAME"   # correct

Command substitution

Use $(...) (preferred) or backticks `...` to put command output into a variable.

Example: timestamped backup filename

#!/bin/bash
OF="myhome_directory_$(date +%Y%m%d).tar.gz"
tar -czf "$OF" /home/linuxconfig

When executed on 2022-02-09 it creates:

myhome_directory_20220209.tar.gz

Why quote $OF? Quoting prevents word-splitting if the filename contains spaces.


Global vs Local variables (scope)

  • Global (script-level) variables are accessible anywhere in the script (including inside functions) unless overridden.

  • Local variables declared with local are scoped to the function where they are defined.

Example:

#!/bin/bash

VAR="global variable"   # global

function myfunc {
  local VAR="local variable"  # local to myfunc
  echo "inside function: $VAR"
}

echo "before func: $VAR"
myfunc
echo "after func: $VAR"

Output:

before func: global variable
inside function: local variable
after func: global variable

local prevents the function from modifying the global VAR.


Exporting variables (environment variables)

export makes a variable available to child processes (subshells / commands you run).

#!/bin/bash
GREETING="hello"
export GREETING
# 02. Variables
python3 -c 'import os; print(os.getenv("GREETING"))'  # prints "hello"

Useful variable patterns

Default values (parameter expansion)

: "${NAME:=default_name}"    # sets NAME to default_name if not set
echo "$NAME"

Or use fallback in-place:

echo "${NAME:-guest}"   # prints NAME if set, otherwise 'guest' (doesn't assign)

Read-only variables

readonly PI=3.14159
# PI=2  # would error

Length, substring, replace

s="hello world"
echo "${#s}"            # length
echo "${s:6:5}"         # substring: 'world'
echo "${s/world/Bash}"  # hello Bash

Arrays

arr=(one two three)
echo "${arr[1]}"       # 'two'
echo "${arr[@]}"       # all elements

Common pitfalls & best practices

  • No spaces around =: VAR = value is wrong; use VAR=value.

  • Always quote expansions when the value may contain spaces: use "$VAR" not $VAR.

  • Use $(...) for command substitution (clearer and nestable) instead of backticks.

  • Prefer local inside functions to avoid accidental global modification.

  • Validate & sanitize user input (never trust untrusted input that ends up in filenames, commands, or URLs).

  • Use set -u (treat unset variables as errors) and set -e where appropriate for safer scripts:

    #!/bin/bash
    set -euo pipefail
    
    • -e: exit on first failing command

    • -u: error on undefined variables

    • -o pipefail: pipeline returns non-zero if any component fails


Example: a small backup script (safe-ish)

#!/bin/bash
set -euo pipefail

# configurable variables
BACKUP_DIR="/home/linuxconfig"
OUT_DIR="/tmp"
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
OF="${OUT_DIR}/myhome_${TIMESTAMP}.tar.gz"

# create backup
tar -czf "$OF" "$BACKUP_DIR"

echo "Backup created: $OF"

Run it and it prints the path of the created archive.


Quick reference / cheatsheet

  • Assign: VAR=value

  • Use: "$VAR"

  • Command output: VAR="$(command)"

  • Local: local VAR="..." (inside a function)

  • Export: export VAR

  • Default: ${VAR:-default} or ${VAR:=default}

  • Length: ${#VAR}

  • Substring: ${VAR:pos:len}


Final notes

Variables are simple but powerful. Use quoting, set -euo pipefail for robustness, prefer local for function scope, and be explicit when exporting variables for child processes. With these practices you’ll write safer, clearer Bash scripts.