---
tags:
  - macOS
  - Tahoe
  - zsh
  - debugging
  - scripting
title: Debugging Zsh Scripts on macOS Tahoe
---

# Debugging Zsh Scripts on macOS Tahoe

Writing scripts is only half the battle; ensuring they run correctly is the other. This guide covers techniques for debugging Zsh scripts on macOS Tahoe. It assumes you are familiar with the basics covered in [Scripting with Zsh on macOS Tahoe](zsh-scripting.md).

## Syntax Checking

Before running a script, you can check it for syntax errors without actually executing the commands.

```zsh
zsh -n myscript.sh
```

If there is no output, the syntax is likely correct. If there is an error, Zsh will point to the line number.

## Execution Tracing

The most common way to debug a script is to see exactly what commands are being executed.

### Tracing the Entire Script

You can run the script with the `-x` (xtrace) flag:

```zsh
zsh -x myscript.sh
```

Or add `set -x` to the top of your script after the shebang:

```zsh
#!/bin/zsh
set -x

echo "This command will be printed before execution"
```

This prints every command and its arguments to the terminal as they are executed, usually prefixed with a `+`.

### Tracing Specific Sections

If you only need to debug a specific part of a long script, you can toggle tracing on and off:

```zsh
#!/bin/zsh

echo "Normal execution..."

set -x
# Debugging starts here
VAR="test"
if [[ "$VAR" == "test" ]]; then
    echo "Variable matches"
fi
set +x

echo "Back to normal execution..."
```

## Verbose Mode

To print the shell input lines as they are read, use the `-v` (verbose) option. This is useful for finding where a script might be crashing if it's not outputting anything.

```zsh
zsh -v myscript.sh
```

## Strict Error Handling

By default, Zsh continues executing a script even if a command fails. To make the script exit immediately upon encountering an error, use `set -e`.

```zsh
#!/bin/zsh
set -e

mkdir /root/protected_folder # This will fail
echo "This line will not run because the previous command failed."
```

## Unbound Variables

Typos in variable names can lead to silent failures. Use `set -u` to treat unset variables as an error.

```zsh
#!/bin/zsh
set -u

NAME="Tahoe"
echo "Welcome to $NMAE" # Typo: This will cause the script to exit with an error
```