Command Palette

Search for a command to run...

Hectal
PHASE 6Intermediate ~14 min· topic 2 of 4

Topic 6.2

Variables, Conditionals & Loops

In one line

Variables store values, conditionals make decisions, and loops repeat work — the same three building blocks every programming language has, expressed in bash's own (occasionally quirky) syntax.

0/4 · 0%

Key ideas

  1. 01

    Bash variables are assigned with NO spaces around the = sign (NAME=value, never NAME = value — the latter is interpreted as running a command called NAME with arguments, a genuinely common beginner error) and read back with a $ prefix (echo $NAME, or ${NAME} when you need to disambiguate it from surrounding text).

  2. 02

    $(command) (command substitution) captures a command's OUTPUT into a variable — TODAY=$(date +%Y-%m-%d) runs date, captures what it printed, and stores that text in TODAY for later use in the script, a genuinely essential building block for any script that needs to act on a command's result.

  3. 03

    An if statement in bash: if [ condition ]; then ... elif [ other ]; then ... else ... fi — note the spaces INSIDE the brackets are mandatory ([condition] without spaces is a syntax error), and the block must end with the literal word fi ('if' spelled backward, bash's consistent closing-keyword convention).

  4. 04

    Common test conditions: [ -f file ] (file exists and is a regular file), [ -d dir ] (directory exists), [ "$a" = "$b" ] (string equality — note = not == for portability, and always quote variables here to avoid errors when a variable is empty or contains spaces), [ $a -eq $b ] (numeric equality — -eq, -lt, -gt etc. for numbers specifically, a genuinely easy detail to mix up with string comparison).

  5. 05

    A for loop: for i in 1 2 3; do echo $i; done iterates over a list of values; for file in *.log; do echo $file; done iterates over every file matching a wildcard (Phase 0's globbing, reused directly) — genuinely one of the most common loop shapes in real scripts, processing every file matching a pattern one at a time.

  6. 06

    A while loop: while [ condition ]; do ... done repeats as long as the condition stays true — commonly used with while read line; do ... done < file.txt to process a file LINE BY LINE, a pattern that shows up constantly when a script needs to act on each line of some input individually.

In your stack

  • →

    A real deployment script might use if [ -f target/app.jar ]; then java -jar target/app.jar; else echo "Build first!"; exit 1; fi — checking a precondition before attempting the actual action, exactly the kind of defensive check that separates a script you can trust from one that fails confusingly when run out of order.

Code & diagrams

variables-and-conditionals.shbash

Every quirk called out above, demonstrated directly.

#!/usr/bin/env bash

# Variable assignment — NO spaces around =
NAME="production-server"
COUNT=3

# Command substitution
TODAY=$(date +%Y-%m-%d)
echo "Today is $TODAY"

# Conditional: does a file exist?
if [ -f "/etc/hosts" ]; then
  echo "hosts file exists"
else
  echo "hosts file missing"
fi

# String vs numeric comparison
STATUS="active"
if [ "$STATUS" = "active" ]; then
  echo "Service is active"
fi

if [ $COUNT -gt 2 ]; then
  echo "Count is greater than 2"
fi
loops.shbash

The two most common loop shapes in real scripts.

#!/usr/bin/env bash

# for loop over a list
for i in 1 2 3; do
  echo "Iteration: $i"
done

# for loop over files matching a wildcard
for file in *.sh; do
  echo "Found script: $file"
done

# while loop reading a file line by line
while read -r line; do
  echo "Line: $line"
done < /etc/hosts

Explain it without notes

01

Why does NAME = value (with spaces) fail in bash, while NAME=value works?

02

What's the practical difference between [ "$a" = "$b" ] and [ $a -eq $b ], and why does using the wrong one matter?

Practice

01

Write a script that loops through every .txt file in a directory and prints its name along with its line count (using wc -l from Phase 2).

02

Write a script using an if/elif/else chain that checks a variable representing a status ("running", "stopped", "unknown") and prints a different message for each case.

Trade-offs

  • ↔

    Bash's conditional and comparison syntax is genuinely quirky and error-prone compared to most general-purpose languages (missing a space, or quoting a variable incorrectly, can silently produce a wrong result rather than a clear error) — for anything beyond a moderate amount of logic, many teams switch to Python for the actual logic while keeping bash for the thin orchestration layer around it, a trade-off worth recognizing rather than forcing everything into bash out of habit.

Done when you can

  • I can declare and read a bash variable, and use command substitution to capture a command's output.

  • I can write an if/elif/else conditional with correct bracket spacing and quoting.

  • I can write both a for loop (over a list or wildcard) and a while loop (reading a file line by line).