2010/6/21 Martin Hansen said:
Hm, I am not making myself clear
( -
Apparently.
It is the status of the ruby
script at hand I want to log. $? is probably barking up the wrong tree
and adding confusion. In Perl I would do this trapping the signal.
#!/usr/bin/env ruby
signal =3D nil
trap("INT") { signal =3D "interupted"; exit }
#trap("TERM") { signal =3D "terminated"; exit }
at_exit { puts "Put this in logfile: #{signal}" }
IMHO it's bad practice to simply exit from a signal handler because
you do not know what the application currently does. It is less
dramatic in Ruby because exit really throws an exception in the
interrupted thread:
$ ruby19 -e 'trap("INT"){ puts "int"; exit 1 }; begin; sleep 20;
rescue Exception =3D> e; p e; end'
int
#<SystemExit: exit>
$
But if you have multiple active threads they are not properly cleaned up:
$ ruby19 -e 'trap("INT"){ puts "INT #{Thread.current}"; exit 1 };
2.times { Thread.new { begin; sleep 20; rescue Exception =3D> e; p e;
ensure p Thread.current; end } }; sleep 30'
INT #<Thread:0x1004e2a4>
#<Thread:0x10042a90 run>
#<Thread:0x10042978 run>
$
Notice how all three threads are terminated but the two background
threads obviously do not see an exception.
In this case it is generally better to somehow globally communicate
that the process is asked to shut down so all parties can properly end
their business.
sleep 5
I have two issues with this: I loose the stack trace that is normally
printed to stderr (I still want that printed to stderr):
./test.rb:10:in `sleep': Interrupt
=A0 =A0 =A0 =A0from ./test.rb:10:in `<main>'
And I fail setting signal as a global variable (if that can be done?) so
I can use it from within a class without getting errors like this:
in `block in <class:Biopieces>': undefined local variable or method
`signal' for Biopieces:Class (NameError)
It seems there is a much simpler solution to what you want - you don't
even need a signal handler for this:
$ ruby19 -e 'begin; sleep 60; rescue Exception =3D> e; p e.class, e,
e.backtrace; end' &
[1] 2664
$ echo $!
2664
$ kill -INT $!
$ Interrupt
Interrupt
["-e:1:in `sleep'", "-e:1:in `<main>'"]
[1]+ Done ruby19 -e 'begin; sleep 60; rescue
Exception =3D> e; p e.class, e, e.backtrace; end'
$
Cheers
robert
--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/