Sometimes you have to try to understand what's going on inside a shell script or a collection of them . If you're lucky, you may be able to easily get a '
sh -x
' output from the script or even scripts. This can be very enlightening but at the same time it can hide some things or at least make them much harder to see in all of the clutter.
The first and biggest thing that '
sh -x
' doesn't give you is shell redirections. If the script makes heavy use of redirecting things into working files that it manipulates, shoves around, and then deletes, a lot of the specifics of this may be invisible to your debugging (although you can usually tell that redirection is going on). This is most likely to apply if the file names are set up dynamically through things like shell variables.
(Perhaps the simplest way of getting '
sh -x
' to report shell variables is to use the '
:
' command, which does nothing but which does appear in '
sh -x
' output. So you can use this as '
: $VAR1
$VAR2 ...
' to create something that only shows up with '
sh -x
' and that fits in naturally with the rest of the '
sh -x
' output.)
The next thing is that while '
sh -x
' reports all of the commands that are run in a shell pipeline, it doesn't particularly report that they're run in a pipeline. Sometimes this is obvious and sometimes it's not. If you're using Bash (including if
/bin/sh
is Bash), you can use
$PS4
to add more information to '
sh -x
' output that may make this clearer, for example including '
$LINENO
'. Including the line number may also make it easier for you (me) to trace the flow of execution of a third party script.
(At least in Bash, '
sh -x
' does report commands run in '
$(...)
' and so on, and in a distinct way. But as with everything else, it doesn't show you the context of that subshell.)
Sometimes information is passed around between parts of the script (or the script and sub-scripts) through environment variables rather than command line arguments. In theory '
sh -x
' makes it possible to know and follow these, because it does print every variable assignment (including the final value). In practice environment variables may be set some distance (in time and space) from when they're used, so reconstructing things may take work. I don't have a good solution to this other than modifying the script to use things like the '
:
' trick to report variable values closer to when they're used.
(In theory you can use '
sh -xv
' to get around some of this. In practice I find the resulting output to be quite hard to read.)
(Mostly I'm writing this down so perhaps I can remember what '
sh -x
' isn't showing me and isn't going to show me the next time I run into a similar situation.)