Tracing Variables in Shell Scripts
Sometimes you need a little more detail when debugging a bash script than bash -x
alone will give you. The following modifies PS4
to contain the line number of each line of output.
#!/bin/bash -x
me=`basename $0`
export 'PS4=+ $me.$LINENO '
function testfunction() {
echo $*
}
testfunction testing
testfunction 123
For example
$ ./test.sh
++ basename ./test.sh
+ me=test.sh
+ export 'PS4=+$me.$LINENO '
+ PS4='+$me.$LINENO '
+ test.sh.7 testfunction testing
+ test.sh.5 echo testing
testing
+ test.sh.8 testfunction 123
+ test.sh.5 echo 123
123
$
If you’re having trouble with a particular variable and cannot figure out where it’s going wrong, combining the above line numbering with the following DEBUG trap may help:
#!/bin/bash -x
me=`basename $0`
export 'PS4=+$me.$LINENO '
trap 'echo "VARIABLE-TRACE> \$somevariable= \"${somevariable}\""' DEBUG
function testfunction() {
echo $*
[[ -n ${somevariable} ]] && unset somevariable
}
somevariable=testing
testfunction ${somevariable}
testfunction ${somevariable}
And here’s the output:
$ ./test.sh
++ basename ./test.sh
+ me=test.sh
+ export 'PS4=+ $me.$LINENO '
+ PS4='+ $me.$LINENO '
+ test.sh.4 trap 'echo "VARIABLE-TRACE> \$somevariable= \"${somevariable}\""' DEBUG
++ test.sh.10 echo 'VARIABLE-TRACE> $somevariable= ""'
VARIABLE-TRACE> $somevariable= ""
+ test.sh.10 somevariable=testing
++ test.sh.11 echo 'VARIABLE-TRACE> $somevariable= "testing"'
VARIABLE-TRACE> $somevariable= "testing"
+ test.sh.11 testfunction testing
+ test.sh.6 echo testing
testing
+ test.sh.7 [[ -n testing ]]
+ test.sh.7 unset somevariable
++ test.sh.12 echo 'VARIABLE-TRACE> $somevariable= ""'
VARIABLE-TRACE> $somevariable= ""
+ test.sh.12 testfunction
+ test.sh.6 echo
+ test.sh.7 [[ -n '' ]]
$