redirect stdout for Kernel.system()?

N

Neil Spring

I'd like to be able to say:

$stdout=File.open("foo.out", "w")
Kernel.system("/bin/echo", "foo")

intead of:

Kernel.system("/bin/echo foo > foo.out")

which requires two processes; forking a "/bin/sh" for
something as simple as redirection is sad.

In ruby1.6.8, this works. In ruby1.8.1 and current cvs, the
behavior is to redirect puts output to the file (yay!), but
the stdout of the child process is not affected (boo.).

I think it is valuable to have the output of system() go to
the currently defined $stdout. From before I found ruby,
perl will allow 'open(STDOUT, ">ick.out"); system("/bin/echo
perl is icky")'.

Is this a bug, intended behavior, or known ambiguity?
Is there an alternative method I haven't thought of?

(test process output follows, maybe it's just me.)

thanks,
-neil


(in the output below, the duplicated messages are probably
due to buffering during the fork)

rf:/tmp> cat ~/foo.rb
#!/usr/bin/ruby

$stdout=File.open("foo.out", "w")
puts "fooble"
Kernel.system("echo", "foo")

Thread.new {
$stdout=File.open("bar.out", "w")
puts "barble"
Kernel.system("echo", "bar")
}.join

Process.fork {
$stdout=File.open("baz.out", "w")
puts "bazzle"
Kernel.system("echo", "baz")
}
Process.wait

rf:/tmp> rm *.out

rf:/tmp> ruby1.8 ~/foo.rb
foo
bar
baz

rf:/tmp> cat baz.out
bazzle

rf:/tmp> cat bar.out
barble
barble

rf:/tmp> cat foo.out
fooble
fooble

rf:/tmp> ruby1.8 --version
ruby 1.8.1 (2003-11-11) [i386-linux]

rf:/tmp> ruby --version
ruby 1.6.8 (2003-07-09) [i386-linux]

rf:/tmp> rm *.out

rf:/tmp> ruby ~/foo.rb

rf:/tmp> cat *.out
barble
bar
bazzle
baz
fooble
foo
 
N

nobu.nokada

Hi,

At Tue, 16 Dec 2003 15:53:43 +0900,
Neil said:
I'd like to be able to say:

$stdout=File.open("foo.out", "w")
Kernel.system("/bin/echo", "foo")

intead of:

Kernel.system("/bin/echo foo > foo.out")

which requires two processes; forking a "/bin/sh" for
something as simple as redirection is sad.

$stdout.reopen("foo.out")
 
A

Andrew Johnson

I'd like to be able to say:

$stdout=File.open("foo.out", "w")
Kernel.system("/bin/echo", "foo")

This gives the desired behavior with 1.8.1p3 and Linux:

oldout = $stdout.dup

$stdout.reopen("foo.out", "w")
puts "fooble"
Kernel.system("echo", "foo")

$stdout.reopen(oldout)
puts 'back to normal'
Kernel.system("echo", "done")

regards,
andrew
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top