redirecting STDOUT

Discussion in 'Ruby' started by Joe Van Dyk, Jun 27, 2005.

  1. Joe Van Dyk

    Joe Van Dyk Guest

    Why doesn't this work?

    (#executable is a function that returns a string that contains a test
    application that spits out some data)

    def start
    pid =3D fork=20
    if pid.nil? # In child
    log =3D File.open(executable + ".log", "w")
    STDOUT.reopen(log)
    STDERR.reopen(log)
    exec executable # Start program
    exit
    else # In parent
    @pid =3D pid # Record new process id
    Process.detach @pid # If the process dies, let it die =20
    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
    Joe Van Dyk, Jun 27, 2005
    #1
    1. Advertising

  2. Joe Van Dyk wrote:
    > Why doesn't this work?
    >
    > (#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.

    Gennady.
    Gennady Bystritksy, Jun 27, 2005
    #2
    1. Advertising

  3. Joe Van Dyk

    Guest

    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.



    Gary Wright
    , Jun 27, 2005
    #3
  4. Joe Van Dyk

    Joe Van Dyk Guest

    Nevermind, it does work! =20

    My test application was the following Ruby application:

    #!/bin/env ruby
    while true
    puts "pid: #{Process.pid}, time: #{Time.now}"
    sleep 0.2
    puts=20
    end

    Does #puts not write to STDOUT by default?


    On 6/27/05, <> wrote:
    >=20
    > On Jun 27, 2005, at 1:37 PM, Joe Van Dyk wrote:
    > > Why doesn't this work?

    >=20
    > Disclaimer: I'm pretty good with Unix System stuff
    > but still learning on the Ruby so...
    >=20
    > > (#executable is a function that returns a string that contains a test
    > > application that spits out some data)
    > >
    > > def start
    > > pid =3D fork
    > > if pid.nil? # In child
    > > log =3D File.open(executable + ".log", "w")
    > > STDOUT.reopen(log)
    > > STDERR.reopen(log)
    > > exec executable # Start program
    > > exit
    > > else # In parent
    > > @pid =3D pid # Record new process id
    > > Process.detach @pid # If the process dies, let it die
    > > monitor # Start monitoring the process' status
    > > end
    > > end

    >=20
    > 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.
    >=20
    > 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.
    >=20
    > 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.
    >=20
    > 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.
    >=20
    >=20
    >=20
    > Gary Wright
    >=20
    >=20
    >
    Joe Van Dyk, Jun 27, 2005
    #4
  5. Joe Van Dyk

    Guest

    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
    >
    > Does #puts not write to STDOUT by default?


    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
    , Jun 27, 2005
    #5
  6. Joe Van Dyk

    Ara.T.Howard Guest

    On Tue, 28 Jun 2005, Joe Van Dyk wrote:

    > Nevermind, it does work!
    >
    > My test application was the following Ruby application:
    >
    > #!/bin/env ruby

    STDOUT.sync = true
    > while true
    > puts "pid: #{Process.pid}, time: #{Time.now}"
    > sleep 0.2
    > puts
    > end
    >
    > Does #puts not write to STDOUT by default?


    you would've seen it eventually...

    you also could do

    STDOUT.flush

    after each write

    cheers.

    -a
    --
    ===============================================================================
    | email :: ara [dot] t [dot] howard [at] noaa [dot] gov
    | phone :: 303.497.6469
    | My religion is very simple. My religion is kindness.
    | --Tenzin Gyatso
    ===============================================================================
    Ara.T.Howard, Jun 27, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jon Landenburer

    redirecting stderr and stdout

    Jon Landenburer, May 12, 2004, in forum: Perl
    Replies:
    1
    Views:
    11,212
    Joe Smith
    May 13, 2004
  2. Sudsy
    Replies:
    0
    Views:
    4,382
    Sudsy
    Jul 18, 2003
  3. Douwe
    Replies:
    1
    Views:
    5,642
    Mike Schilling
    Jan 12, 2004
  4. Alexander Stippler

    redirecting stdout to ostream

    Alexander Stippler, Feb 5, 2004, in forum: C++
    Replies:
    4
    Views:
    7,289
    Alexander Stippler
    Feb 6, 2004
  5. Elad
    Replies:
    0
    Views:
    411
Loading...

Share This Page