Skip to main content

Debug Command

The utah debug command compiles Utah (.shx) source files into bash (.sh) scripts with embedded source-map comments. Each statement in the generated bash is preceded by a comment showing which .shx line produced it, making it easy to trace runtime errors back to the original source.

Note: utah debug adds source-map comments (# [shx:N]) to the compiled bash output. This is different from script.enableDebug(), which emits set -x to turn on bash's built-in execution tracing. See Script Directives for set -x tracing. The two can be combined for maximum visibility.

Basic Usage

utah debug <file.shx> [-o, --output <output.sh>]

Examples

Simple Debug Compilation

utah debug script.shx

This creates script.sh with source-map comments in the same directory.

Custom Output File

utah debug script.shx -o /path/to/debug-output.sh
utah debug script.shx --output /path/to/debug-output.sh

How It Works

The debug command performs the same transpilation as compile, but injects a # [shx:<line>] comment before every compiled statement. The comment includes the 1-based line number and the original .shx source text.

Example

Input (script.shx):

let name: string = "Utah";
console.log("Hello");
if (name === "Utah") {
console.log("found it");
}

Output with utah debug (script.sh):

#!/bin/bash

# [shx:1] let name: string = "Utah";
name="Utah"
# [shx:2] console.log("Hello");
echo "Hello"
# [shx:3] if (name === "Utah") {
if [ "${name}" = "Utah" ]; then
# [shx:4] console.log("found it");
echo "found it"
fi

Compare with regular utah compile (script.sh):

#!/bin/bash

name="Utah"
echo "Hello"
if [ "${name}" = "Utah" ]; then
echo "found it"
fi

Source-Map Comment Format

Each source-map comment follows this format:

# [shx:<line_number>] <original_source_line>
  • <line_number>: 1-based line number from the original .shx file
  • <original_source_line>: The trimmed source text of that line

Comments appear for all compiled statements, including those nested inside control structures, functions, and loops.

When to Use Debug vs Compile

ScenarioCommand
Production deploymentutah compile
Troubleshooting runtime errorsutah debug
Reviewing generated bash logicutah debug
CI/CD pipelinesutah compile
Learning how Utah translates constructsutah debug

Troubleshooting with Debug Output

When a bash script fails at runtime, the source-map comments help you locate the problem:

$ bash script.sh
script.sh: line 14: some_command: command not found

Open script.sh and look at line 14. The nearest # [shx:N] comment above it tells you which .shx line to fix:

# [shx:7] let result: string = someCommand();
result=$(some_command) # ← line 14, the error is here

Now you know the issue is on line 7 of your .shx source.

Tips

  1. Use debug during development, switch to compile for production
  2. Source-map comments are valid bash — debug-compiled scripts run identically to regular compiled scripts
  3. Combine with bash -x for even deeper tracing:
utah debug script.shx -o debug-script.sh
bash -x debug-script.sh

This gives you both Utah source mapping and bash execution tracing.

Integration Examples

Debug Build Script

#!/bin/bash
# debug-build.sh - Compile with source maps for development

for file in src/*.shx; do
basename=$(basename "$file" .shx)
utah debug "$file" -o "debug/$basename.sh"
echo "✅ Debug compiled: $basename.sh"
done

Makefile Integration

SOURCES := $(wildcard src/*.shx)
DEBUG_TARGETS := $(SOURCES:src/%.shx=debug/%.sh)

debug: $(DEBUG_TARGETS)

debug/%.sh: src/%.shx
utah debug $< -o $@

.PHONY: debug