Lesson 1 | Working with Variables (Modern Bash) |
Objective | Create, read, export, and manipulate variables (scalars and arrays) in Bash scripts safely and idiomatically. |
Variables store data your script needs, such as paths, flags, counters, user input, and more. In Bash, you have shell (local) variables, environment variables (inherited by child processes), and special parameters such as $0
, $1
, and $?
. This lesson shows how to declare, read, export, and transform values reliably.
export
.Assignments have no spaces around =
. Use double quotes when expanding variables to prevent unwanted word splitting and globbing.
name="Ada Lovelace"
count=3 # numeric (still a string until used in arithmetic)
echo "$name has ${count} tasks"
Unset or make constant:
unset name
declare -r VERSION="1.0" # readonly (fails if reassigned)
A variable is local to the current shell by default. Use export
to pass it to child processes:
api_token="abc123"
export api_token
# Now child processes (e.g., programs you exec) can read $api_token
Startup files vary by shell and login mode. For Bash: system-wide files (e.g., /etc/profile
) plus per-user files like ~/.bash_profile
and ~/.bashrc
commonly initialize environment variables.
Reference a variable with $var
or ${var}
(braces are safer in mixed text):
file="/tmp/report"
echo "Writing to ${file}.txt"
Capture command output with $(…)
:
today=$(date +%F)
echo "Run date: $today"
Use $((…))
for integer arithmetic:
a=7; b=5
sum=$((a + b)) # 12
((count++)) # increment in-place
if (( sum > 10 )); then echo "big"; fi
${var:-default}
(do not set) / ${var:=default}
(set)${#var}
${var:offset:length}
${var/pat/repl}
(first), ${var//pat/repl}
(all)${var:?message}
user_dir=${HOME:-/home/default}
msg="alpha beta beta"
echo "${#msg}" # 15
echo "${msg/beta/gamma}" # alpha gamma beta
echo "${msg//beta/gamma}" # alpha gamma gamma
Prompt and read safely with read -r
(prevents backslash escapes). Use -p
for a prompt, -a
to read into an array.
read -r -p "Project name: " project
read -r -a tags <<< "one two three" # tags=(one two three)
echo "Project=$project, first tag=${tags[0]}"
files=(/var/log/syslog /var/log/auth.log)
files+=("/var/log/kern.log")
echo "Count: ${#files[@]}"
for f in "${files[@]}"; do
printf '%s\n' "$f"
done
declare -A ports=([http]=80 [https]=443)
echo "HTTPS port is ${ports[https]}"
for key in "${!ports[@]}"; do
echo "$key => ${ports[$key]}"
done
"$var"
and "${arr[@]}"
.$(…)
over backticks for command substitution."${file}.txt"
.local
inside functions to avoid leaking names.${var:?message}
.