(#executable is a function that returns a string that contains a test
application that spits out some data)
def start
pid = fork
if pid.nil? # In child
log = File.open(executable + ".log", "w")
STDOUT.reopen(log)
STDERR.reopen(log)
exec executable # Start program
exit
else # In parent @pid = pid # Record new process id
Process.detach @pid # If the process dies, let it die
monitor # Start monitoring the process' status
end
end
Well, it works for the most part. The log file gets created, but
nothing gets written to it. Am I not redirecting output correctly?
(#executable is a function that returns a string that contains a test
application that spits out some data)
def start
pid = fork if pid.nil? # In child
log = File.open(executable + ".log", "w")
STDOUT.reopen(log)
STDERR.reopen(log)
exec executable # Start program
exit
else # In parent @pid = pid # Record new process id
Process.detach @pid # If the process dies, let it die monitor # Start monitoring the process' status
end
end
Well, it works for the most part. The log file gets created, but
nothing gets written to it. Am I not redirecting output correctly?
Thanks,
Joe
Thanks,
Joe
Are you sure your "executable" is producing anything when launched the way you do it? You may try some STDERR.puts before "exec executable" to know for sure that something must be there. Also, I would do log.close before exec as the file descriptor is cloned anyway for stdout and stderr.
Disclaimer: I'm pretty good with Unix System stuff
but still learning on the Ruby so...
(#executable is a function that returns a string that contains a test
application that spits out some data)
def start
pid = fork
if pid.nil? # In child
log = File.open(executable + ".log", "w")
STDOUT.reopen(log)
STDERR.reopen(log)
exec executable # Start program
exit
else # In parent @pid = pid # Record new process id
Process.detach @pid # If the process dies, let it die
monitor # Start monitoring the process' status
end
end
This worked for me (Mac OS X 10.4, Ruby 1.8.2). Check the permissions
on the log file. If was created in earlier tests as a read-only file maybe
that is why the program fails now.
If you have something like ktrace or truss on your system, trace
the ruby program and then look at the dump. You can see exactly
what system calls are being made (open/read/write/etc) and also
what errors, if any, are being returned.
Try using some standard program such as /bin/date instead of executable
just to make sure it isn't a problem with your test program. You'll
probably want a different path for the log file in that case.
If 'monitor' is going to watch the child process then just incorporate
calls to Process.wait(@pid) as part of 'monitor' instead of
Process.detach. If you have both Process.detach and monitor periodically
calling Process.wait, you'll never be sure which thread is going to
catch the exiting child.
My test application was the following Ruby application:
#!/bin/env ruby
while true
puts "pid: #{Process.pid}, time: #{Time.now}"
sleep 0.2
puts
end
Does #puts not write to STDOUT by default?
···
On 6/27/05, gwtmp01@mac.com <gwtmp01@mac.com> wrote:
On Jun 27, 2005, at 1:37 PM, Joe Van Dyk wrote:
> Why doesn't this work?
Disclaimer: I'm pretty good with Unix System stuff
but still learning on the Ruby so...
> (#executable is a function that returns a string that contains a test
> application that spits out some data)
>
> def start
> pid = fork
> if pid.nil? # In child
> log = File.open(executable + ".log", "w")
> STDOUT.reopen(log)
> STDERR.reopen(log)
> exec executable # Start program
> exit
> else # In parent
> @pid = pid # Record new process id
> Process.detach @pid # If the process dies, let it die
> monitor # Start monitoring the process' status
> end
> end
This worked for me (Mac OS X 10.4, Ruby 1.8.2). Check the permissions
on the log file. If was created in earlier tests as a read-only file
maybe
that is why the program fails now.
If you have something like ktrace or truss on your system, trace
the ruby program and then look at the dump. You can see exactly
what system calls are being made (open/read/write/etc) and also
what errors, if any, are being returned.
Try using some standard program such as /bin/date instead of executable
just to make sure it isn't a problem with your test program. You'll
probably want a different path for the log file in that case.
If 'monitor' is going to watch the child process then just incorporate
calls to Process.wait(@pid) as part of 'monitor' instead of
Process.detach. If you have both Process.detach and monitor
periodically
calling Process.wait, you'll never be sure which thread is going to
catch the exiting child.
Buffering. When you run this program with output
associated with the terminal, STDOUT is line buffered
so you see each line right after puts executes.
When you redirect STDOUT to a file, the IO is not
line buffered but instead buffered into blocks.
When I tested your program, I didn't see any output
in the file until puts had generated 4k worth of
data at which point it was flushed to the file
system.
You'll have to put in explicit calls to flush if
you expect to see the output in a different way or
change STDOUT to be line buffered.
Gary Wright
···
On Jun 27, 2005, at 4:52 PM, Joe Van Dyk wrote:
Nevermind, it does work!
My test application was the following Ruby application:
#!/bin/env ruby
while true
puts "pid: #{Process.pid}, time: #{Time.now}"
sleep 0.2
puts
end