预计阅读本页时间:-
Structure of the Debugger
The bashdb debugger works by taking a shell script and turning it into a debugger for itself. It does this by concatenating debugger functionality and the target script, which we'll call the guinea pig script, and storing it in another file that then gets executed. The process is transparent to users—they will be unaware that the code that is executing is actually a modified copy of their script.
The bash debugger has three main sections: the driver, the preamble, and the debugger functions.
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
The driver script
The driver script is responsible for setting everything up. It is a script called bashdb and looks like this:
# bashdb - a bash debugger
# Driver Script: concatenates the preamble and the target script
# and then executes the new script.
echo 'bash Debugger version 1.0'
_dbname=${0##*/}
if (( $# < 1 )) ; then
echo "$_dbname: Usage: $_dbname filename" >&2
exit 1
fi
_guineapig=$1
if [ ! -r $1 ]; then
echo "$_dbname: Cannot read file '$_guineapig'." >&2
exit 1
fi
shift
_tmpdir=/tmp
_libdir=.
_debugfile=$_tmpdir/bashdb.$$ # temporary file for script that is
being debugged
cat $_libdir/bashdb.pre $_guineapig > $_debugfile
exec bash $_debugfile $_guineapig $_tmpdir $_libdir "$@"
bashdb takes as the first argument the name of guinea pig file. Any subsequent arguments are passed on to the guinea pig as its positional parameters.
If no arguments are given, bashdb prints out a usage line and exits with an error status. Otherwise, it checks to see if the file exists. If it doesn't, exist then bashdb prints a message and exits with an error status. If all is in order, bashdb constructs a temporary file in the way we saw in the last chapter. If you don't have (or don't have access to) /tmp on your system, then you can substitute a different directory for _tmpdir.[11] The variable _libdir is the name of the directory that contains files needed by bashdb (bashdb.pre and bashdb.fns). If you are installing bashdb on your system for everyone to use, you might want to place them in /usr/lib.
The cat statement builds the modified copy of the guinea pig file: it contains the script found in bashdb.pre (which we'll look at shortly) followed by a copy of the guinea pig.
exec
The last line runs the newly created script with exec, a statement we haven't discussed yet. We've chosen to wait until now to introduce it because—as we think you'll agree—it can be dangerous. exec takes its arguments as a command line and runs the command in place of the current program, in the same process. In other words, a shell that runs exec will terminate immediately and be replaced by exec's arguments.[12]
In our script, exec just runs the newly constructed shell script, i.e., the guinea pig with its debugger, in another shell. It passes the new script three arguments—the name of the original guinea pig file ($_guineapig), the name of the temporary directory ($_tmpdir), and the name of the library directory ($_libdir)—followed by the user's positional parameters, if any.