Updated: 2017-04-03 05:17 EDT

1 Debugging shell scripts using options -v and -x

You can have the shell display statements in a shell script as they are either read or executed using the -v or -x options.

An example:

#!/bin/sh -u
#  $0 filename directory
# Find hard links to filename located in directory
file=$1
directory=$2
inode=$( ls -id "$file" | awk '{print $1}' )
find "$directory" -inum "$inode"

Running the above script:

$ ./example.sh
./example.sh: 4: ./example.sh: 1: parameter not set

$ sh -u example.sh
example.sh: 4: example.sh: 1: parameter not set

$ sh -uv example.sh
#!/bin/sh -u
#  $0 filename directory
# Find hard links to filename located in directory
file=$1
i.sh: 4: i.sh: 1: parameter not set

Above, the use of the -v option shows which statement the shell was about to execute when it encountered the variable with the undefined value. We can supply two arguments to the script and see how the output changes:

$ sh -uv example.sh foo bar
#!/bin/sh -u
#  $0 filename directory
# Find hard links to filename located in directory
file=$1
directory=$2
inode=$( ls -id "$file" | awk '{print $1}' )
ls: cannot access foo: No such file or directory
find "$directory" -inum "$inode"
find: missing argument to `-inum'

Above, the use of the -v option lets us see the lines that are producing the error messages, but we don’t see the actual values interpolated by the Variable Expansions.

Using -x, we see the lines as they are executed, with the variables expanded:

$ sh -ux example.sh foo bar
+ file=foo
+ directory=bar
+ ls -id foo
+ awk {print $1}
ls: cannot access foo: No such file or directory
+ inode=
+ find bar -inum
find: missing argument to `-inum'

Above, we see that the failing ls command meant that the variable $inode had no value, leading to the error message from the find command inside the script.

You can get better-looking -x debugging output by using the bash command instead of sh that is usually linked to dash on Ubuntu systems:

$ bash -ux example.sh foo bar
+ file=foo
+ directory=bar
++ ls -id foo
++ awk '{print $1}'
ls: cannot access foo: No such file or directory
+ inode=
+ find bar -inum ''
find: missing argument to `-inum'

Above, the bash shell shows empty arguments and arguments with special characters correctly single-quoted, and it shows nested Command Substitutions with double leading ++ signs, making the debug output easier to read.

To best diagnose script problems, test your script incrementally, adding one or two lines at a time as you build it up into its final form.

Author: 
| Ian! D. Allen, BA, MMath  -  idallen@idallen.ca  -  Ottawa, Ontario, Canada
| Home Page: http://idallen.com/   Contact Improv: http://contactimprov.ca/
| College professor (Free/Libre GNU+Linux) at: http://teaching.idallen.com/
| Defend digital freedom:  http://eff.org/  and have fun:  http://fools.ca/

Plain Text - plain text version of this page in Pandoc Markdown format

Campaign for non-browser-specific HTML   Valid XHTML 1.0 Transitional   Valid CSS!   Creative Commons by nc sa 3.0   Hacker Ideals Emblem   Author Ian! D. Allen