An acceptable solution was proposed which periodically reads a file
that controls turning on some debugging switches.
Another variation on that idea is to install a signal handler. This
has an advantage of not requiring any sort of polling which means the
debugging will have a more instantaneous effect, doesn't have to
appear in a loop or appear more than once or other than at the beginning
of the file.
Here's an example. In file debugit.sh:
# This is my extra debug hook
trap 'set -x' USR1 ; trap 'set +x' USR2
echo $$
while : ; do
date=$(date)
echo "$date"
sleep 2
done
Now run:
$ bash debugit.sh
9386
Thu Jun 19 02:31:09 EDT 2008
Thu Jun 19 02:31:11 EDT 2008
From some other shell:
kill -USR1 9386
And back to the running program...
(debugit.sh:5): - [4,0]
:
((debugit.sh:6): - [4,1]
date
(debugit.sh:6): - [4,0]
date='Thu Jun 19 02:31:19 EDT 2008'
(debugit.sh:7): - [4,0]
echo 'Thu Jun 19 02:31:19 EDT 2008'
Thu Jun 19 02:31:19 EDT 2008
(debugit.sh:8): - [4,0]
sleep 2
(debugit.sh:5): - [4,0]
:
((debugit.sh:6): - [4,1]
date
(debugit.sh:6): - [4,0]
date='Thu Jun 19 02:31:21 EDT 2008'
(debugit.sh:7): - [4,0]
echo 'Thu Jun 19 02:31:21 EDT 2008'
Thu Jun 19 02:31:21 EDT 2008
(debugit.sh:8): - [4,0]
sleep 2
((debugit.sh:9): - [4,0]
To turn off debugging:
kill -USR2 9386
set +x
Thu Jun 19 02:31:23 EDT 2008
Thu Jun 19 02:31:25 EDT 2008
...
In the above listing, my bash-specific PS4 setting is:
declare -x PS4="(\${BASH_SOURCE}:\${LINENO}): \${FUNCNAME[0]} - [\${SHLVL},\${BASH_SUBSHELL}]\\n"
This works best for version 3.0 and above.
Going further, if you've got the bash debugger (http://bashdb.sf.net)
installed, it comes with a hook to allow it to get called when an
interrupt is given to the program. Find the file bashdb-trace
installed on your system. On my Ubuntu box, Debian bashdb package
installs it in /usr/share/bashdb/bashdb-trace. Now change your program
like this:
# This is my extra debug hook
source /usr/share/bashdb/bashdb-trace
echo $$
while : ; do
date=$(date)
echo "$date"
sleep 2
done
And run:
bash ./debugit2.sh
Bourne-Again Shell Debugger, release bash-3.1-0.08
Copyright 2002, 2003, 2004, 2006 Rocky Bernstein
This is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
9435
Thu Jun 19 02:43:06 EDT 2008
Thu Jun 19 02:43:08 EDT 2008
Sent it an "interrupt" signal
kill -INT 9435
And back to the running program:
Program received signal SIGINT (2)...
->0 in file `./debugit2.sh' at line 251 # not sure where 251 came from!
##1 main() called from file `./debugit2.sh' at line 0
bashdb<0> where
->0 in file `./debugit2.sh' at line 9 # but this line number is now right
##1 main() called from file `./debugit2.sh' at line 0
bashdb<1> list 1
1: # This is my extra debug hook
2: source /usr/share/bashdb/bashdb-trace
3:
4: echo $$
5: while : ; do
6: date=$(date)
7: echo "$date"
8: sleep 2
9:==>done
bashdb<2> s
(./debugit2.sh:5):
5: while : ; do
bashdb<3> s
(./debugit2.sh:6):
6: date=$(date)
bashdb<4>
Some of this is described in the bashdb manual:
http://bashdb.sourceforge.net/bashdb.html#SEC10
The hooks and the debugger in general are not as robust as I would
like -- feel free to contribute!
Thats was me and many thanx for your help. I would come back to you
soon on this.
Ciao
> On 19 Jun, 08:02, ro...@panix.com (R. Bernstein) wrote:
>> A little while back someone asked about debugging a running shell
>> script. (Alas, the post from less than 3 weeks ago has expired in my
>> news reader.)
>>
>> An acceptable solution was proposed which periodically reads a file
>> that controls turning on some debugging switches.
>>
>> Another variation on that idea is to install a signal handler. This
>> has an advantage of not requiring any sort of polling which means the
>> debugging will have a more instantaneous effect, doesn't have to
>> appear in a loop or appear more than once or other than at the beginning
>> of the file.
>>
>> Here's an example. In file debugit.sh:
>>
>> # This is my extra debug hook
>> trap 'set -x' USR1 ; trap 'set +x' USR2
>>
>>
>> From some other shell:
>> kill -USR1 9386
>>
>>
>> To turn off debugging:
>> kill -USR2 9386
>>
>
> Thats was me and many thanx for your help. I would come back to you
> soon on this.
>
> Ciao
>
Hi,
another idea using ^C - = q (set -x, set +x, exit)
trap 'read -n1 a;case "$a" in q)exit;;-)set -x;;=)set +x;esac' 2
> Hi,
> another idea using ^C - = q (set -x, set +x, exit)
>
> trap 'read -n1 a;case "$a" in q)exit;;-)set -x;;=)set +x;esac' 2
This is cool. I'd probably add a prompt before the read, and the -n1
option doesn't seem to be in POSIX (for those of you who use
dash/ash).
More serious though is that one may or may not have access to
stdin, e.g. if your script is running as a daemon. So the other code
may still be preferable in that kind of situation.
And here's yet another variation which eliminates the need to modify the
script. Put the following in a file, say "debug_wrapper":
# adjust trap as suggested above
trap 'set -x' USR1 ; trap 'set +x' USR2
source "$@"
Then run run your program:
debug_wrapper my_program
With all of the variation given, you have an instant debugger. ;-)
But there are a couple of thing problems of the "source" method. If
the program you are running uses $0 it will report your debug_wrapper
rather than itself. Probably in the next release of bashdb I'll add a
built-in command to set $0; bashdb or such a wrapper above could then
use that to hide itself a little bit more.
Second, the stack nesting will be a little different. In another
posting I showed how you could tell if your program was source'd or
not and this change will confuse something like this.
Just wanted to know if the above explantion is just valid on bash
shell. as I currently operate on Korn .
Ciao
Bye, Jojo