Redirect stdout for Kernel.system()?

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

You can use IO.popen for that:
http://whytheluckystiff.net/ruby/pickaxe/html/ref_c_io.html#IO.popen

robert

“Neil Spring” nspring@cs.washington.edu schrieb im Newsbeitrag
news:20031216065336.GA14158@cs.washington.edu…

···

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

Hi,

···

At Tue, 16 Dec 2003 15:53:43 +0900, Neil Spring wrote:

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”)


Nobu Nakada

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

···

On Tue, 16 Dec 2003 15:53:43 +0900, Neil Spring nspring@cs.washington.edu wrote:

I’d like to be able to say:

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

thanks! that was exactly what I needed.

-neil

···

On Wed, Dec 17, 2003 at 03:47:52AM +0900, nobu.nokada@softhome.net wrote:

Hi,

I’d like to be able to say:

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

$stdout.reopen(“foo.out”)