Say you've got this my-command.sh :
#! /usr/bin/env bash add_one() { echo $(($1 + 1)) } add_two() { echo $(($1 + 2) } add_one $(add_two 3)Running it yields just the result:
$ my-command.sh 1 4Now, you want to see exactly how my-command.sh arrived at that result:
$ bash -x my-command.sh 1 ++ add_two 1 ++ echo 3 + add_one 3 + echo 4 4You can also turn this on inside your my-command.sh with:
set -o xtraceNow, when your scripts get bigger and hairer, what you'd like is more context, with clickable links on each line to open the corresponding source file with the statement and so on.
Here's how. Set xtrace format is governed by the PS4 variable. Here's what I've got:
export PS4='${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]}() - [${SHLVL},${BASH_SUBSHELL},$?] 'With this, I get xtrace debug output like this:
t.sh:11: main() - [4,1,0] add_two 1 t.sh:8: add_two() - [4,1,0] echo 3 t.sh:11: main() - [4,0,0] add_one 3 t.sh:4: add_one() - [4,0,0] echo 4 4Running this from within an emacs compile buffer, each line is clickable, taking me to the place in the source code (this can be a command consisting of many .sh files). Pretty neat, yeah?
Happy debugging!