-v
and -x
Updated: 2017-04-03 05:17 EDT
-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.
-v
option tells the shell to display each line as it is read by the script, including comments and blank lines. (Loop statements are only printed once, as they are first read.)-x
option tells the shell to display only the lines that are actually executed by the script. The lines will show the results of Variable and Command Expansions. Loop statements will print over and over each time the loop iterates.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.