Hello,
I would like to, for a given script, to print the exit status - such as
normal, interrupted, terminated, etc. to a log file. How can I do that?
Martin
Hello,
I would like to, for a given script, to print the exit status - such as
normal, interrupted, terminated, etc. to a log file. How can I do that?
Martin
2010/6/18 Martin H. [email protected]:
I would like to, for a given script, to print the exit status - such as
normal, interrupted, terminated, etc. to a log file. How can I do that?
Not clear what you intend to do. Is the script a Ruby script? Then
you do it with any process. Do you want to print the status of
another program in a Ruby script? Where do you want to print that?
Cheers
robert
I would like to print the exit status from within the current Ruby
script to a log file. I have been messing a bit with $?, but that way I
get “pid 8144 exit 0” in the log file and “Interrupted” goes to terminal
The log file is just a file dedicated to this script.
Cheers,
Martin
Robert K. wrote:
2010/6/18 Martin H. [email protected]:
I would like to, for a given script, to print the exit status - such as
normal, interrupted, terminated, etc. to a log file. How can I do that?Not clear what you intend to do. Is the script a Ruby script? Then
you do it with any process. Do you want to print the status of
another program in a Ruby script? Where do you want to print that?Cheers
robert
Please don’t top post.
2010/6/21 Martin H. [email protected]:
I would like to print the exit status from within the current Ruby
script to a log file. I have been messing a bit with $?, but that way I
get “pid 8144 exit 0” in the log file and “Interrupted” goes to terminal
- I wanted “Interrupted” in the log file.
“Interrupted” is not an exit status. This is most likely written by
the other process that you started. You either need to catch the
other process’s output (most likely stderr) or invent a mechanism to
report the interruption via the exit status (this works only if you
have control over the other process’s code). Then you can interpret
the exit status to write your log message.
irb(main):008:0> system “true”
=> true
irb(main):009:0> $?
=> #<Process::Status: pid 712 exit 0>
irb(main):010:0> $?.exitstatus
=> 0
If you want to catch the output you can use one of the popen methods,
e.g.
irb(main):001:0> require ‘open3’
=> true
irb(main):002:0> Open3.popen3 “ls”, “nonexistent” do |si,so,serr,th|
irb(main):003:1* p serr.read
irb(main):004:1> st = th.value
irb(main):005:1> p st, st.exitstatus
irb(main):006:1> end
“ls: cannot access nonexistent: No such file or directory\n”
#<Process::Status: pid 3160 exit 2>
2
=> [#<Process::Status: pid 3160 exit 2>, 2]
I have not been able to make
trap() do the trick, and with trap I loose the default exit and stack
trace output (I think trap is to be avoided).
trap in your Ruby script will trap signals for this process not the
forked process - unless you use the block form of fork in which case I
believe the child inherits all signal handlers.
Kind regards
robert
2010/6/21 Martin H. [email protected]:
Hm, I am not making myself clear :o( -
Apparently.
signal = nil
trap(“INT”) { signal = “interupted”; exit }
#trap(“TERM”) { signal = “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 => 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 => 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.
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 => e; p e.class, e,
e.backtrace; end’ &
[1] 2664
$ echo $!
2664
$ kill -INT $!
$ Interrupt
Interrupt
[“-e:1:in sleep'", "-e:1:in
'”]
[1]+ Done ruby19 -e ‘begin; sleep 60; rescue
Exception => e; p e.class, e, e.backtrace; end’
$
Cheers
robert
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 => e; p e.class, e,
e.backtrace; end’ &
[1] 2664
$ echo $!
2664
$ kill -INT $!
$ Interrupt
Interrupt
[“-e:1:insleep'", "-e:1:in
'”]
[1]+ Done ruby19 -e ‘begin; sleep 60; rescue
Exception => e; p e.class, e, e.backtrace; end’
That indeed looks very clever. But I note that if the script is
terminated I get “SignalException” and not “Terminated”. Also, I note
that backtrace is a list, and I was wondering what method Ruby normally
uses to reformat and pretty print that (Ruby is not simply printing and
indenting the lines).
However, I fail to see how this exception handling should be integrated
in practice with my code that currently relies on an at_exit call (line
84):
http://code.google.com/p/biopieces/source/browse/trunk/code_ruby/Maasha/lib/biopieces.rb
And just a reminder that I am trying to create super simplified scripts
of this type:
Cheers,
Martin
Hm, I am not making myself clear :o( - 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.
trap in your Ruby script will trap signals for this process not the
forked process - unless you use the block form of fork in which case I
believe the child inherits all signal handlers.
#!/usr/bin/env ruby
signal = nil
trap(“INT”) { signal = “interupted”; exit }
#trap(“TERM”) { signal = “terminated”; exit }
at_exit { puts “Put this in logfile: #{signal}” }
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 from ./test.rb:10:in
’
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)
Cheers,
Martin
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs