← Back to Bash Course | Chapter 12: Error Handling & Debugging | Lesson 6 of 12

set -u (Undefined Variables) and set -x (Trace Mode)

set -u makes a script complain if you try to use a variable that was never given a value, and set -x prints every command as it runs so you can watch the script's execution step by step.

Catching Unset Variables

With set -u active, referencing a variable that was never assigned causes an immediate error and non-zero exit, which helps catch typos in variable names early instead of them silently expanding to nothing.

Example: Catching Unset Variables

bash
#!/bin/bash
(
    set -u
    echo "$defined_var" 2>/dev/null
) ; defined_var="hello"
(
    set -u
    echo "now it's set: $defined_var"
)

Safely Demonstrating set -u's Error

Running the failing case inside a subshell and checking its overall result with || lets a script show what set -u catches without letting that failure end the whole script.

Example: Safely Demonstrating set -u's Error

bash
#!/bin/bash
(set -u; echo "$totally_undefined_variable") 2>/dev/null || echo "caught: set -u stopped an unset variable reference"

Providing Defaults to Avoid set -u Errors

${var:-default} expands to default whenever var is unset (or empty), which is the standard way to make a script compatible with set -u while still allowing optional variables, like positional parameters that may not be given.

Example: Providing Defaults to Avoid set -u Errors

bash
#!/bin/bash
set -u
name="${1:-anonymous}"
echo "Hello, $name"

Tracing Execution with set -x

set -x makes bash print each command to stderr, prefixed with +, right before running it, with variables already expanded to their actual values. This is one of the fastest ways to see exactly what a script is doing.

Note: Redirect the trace output separately with exec 2>trace.log if you want to keep it out of the normal terminal output.

Warning: set -x can print sensitive values like passwords or tokens; avoid it around code that handles secrets.

Example: Tracing Execution with set -x

bash
#!/bin/bash
set -x
num=5
double=$((num * 2))
set +x
echo "tracing disabled again; double is $double"
Common Mistakes
  1. Forgetting set -u treats an unset variable as an error even in something as common as $1 when no argument was passed, which needs a default like ${1:-}.
  2. Leaving set -x enabled in production output, which can leak sensitive values (like passwords stored in variables) into logs.
  3. Assuming set -u catches a variable that is set to an empty string; empty and unset are different, and set -u only complains about the latter.
Chapter Summary
  • set -u causes an error when an unset variable is referenced, instead of silently treating it as an empty string.
  • ${var:-default} provides a fallback value and avoids a set -u error for a variable that might not be set.
  • set -x prints each command (with variables expanded) to stderr right before it executes, which is invaluable for debugging.
  • set +u and set +x turn each mode back off; both can also be combined with set -e as part of a strict-mode header.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.