System calls

so I can get the standard output from a system call:

s = date

and I can get the return value:

system( “date” )

and I have no idea how to get the standard error:

???

but what I really want is all three, like:

out, err, ret = really_cool_system( “date” )

Please Help!

TIA
Michael Garriss

Joel VanderWerf wrote:

So, so summarize: if you want your accessors to appear in the standard
accessors section, it’s easy. otherwise it’s harder.

Actually, the caller sees the accessors just like any other accessors,
so the easy approach will work for me. Is there anything I can do?

OK - I’ve added an --accessor option; check out the latest CVS.

rdoc --accessor db_opt,option,param  fred.rb

or
rdoc -A db_opt,option,param fred.rb

will accept stuff like

class Mine
   db_opt :buffer_size, :pool
   param  :name
   option :line_size, :protocol

and report them alongside normal attributes. You can have multiple
–accessor parameters.

Cheers

Dave

This is almost what you want, except that the exit code is wrong and I don’t
know how to fix it:

require ‘open3’
module Kernel
private
def really_cool_system(*args)
inp, out, err = Open3.popen3(*args)
ret1 = ret2 = nil
t1 = Thread.new do
inp.close
end
t2 = Thread.new do
ret1 = out.read
out.close
end
t3 = Thread.new do
ret2 = err.read
err.close
end
t1.join
t2.join
t3.join
return ret1, ret2, $?
end
end

irb(main):024:0> really_cool_system(“ls”,“/dev/null”,“/dev/foo”)
=> [“/dev/null\n”, “ls: /dev/foo: No such file or directory\n”, 65280]

Regards,

Brian.

···

On Tue, May 27, 2003 at 10:24:50PM +0900, mgarriss wrote:

so I can get the standard output from a system call:

s = date

and I can get the return value:

system( “date” )

and I have no idea how to get the standard error:

???

but what I really want is all three, like:

out, err, ret = really_cool_system( “date” )

Recently I implemented a facility for such cases and if you are
interested I can send it to you (I am not sure it is worth enough to be
sent to RAA). It does not spawn threads, all is done with IO#select.

I called it “launch” and made it available through the Kernel. So in
your case it can be used as:

require ‘launch’
messages = launch “date”

It returns an array of message arrays, the first element – messages
read from the command’s stdout, the second – from the stderr.
If the command is killed or returns with error (return code is not 0),
exception TerminateError is raised. If you rescue it, you can get the
reason for termination (signal or non-zero return) and the return code
(signal number if killed). Stderr messages are also available from the
exception class.

In general, it was designed for launching a pipeline of commands with
access to all error messages and return codes from all commands in the
pipeline. Unfortunately, when you do it with system(“command1 |
command2 |command3”), you may not even know that command1 or command2
terminated abnormally as shell returns the code of the last command in
a pipeline.

General syntax is:
launch [, ] <command_1> [, <command_2> … [, <command_N>] { |
line_0, line_1, … line_N | block } → anArray
- an optional IO object. If specified, the first command’s stdin
will be redirected from this IO object. Otherwise “/dev/null” is used.
- all commands are spawned (fork & exec) with stdout of the
previous command redirected to stdin of the next command. Stdout of the
last command is read out and messages are stored in the array available
as the first element of the returned array. All other elements of the
returned array store error messages from stderr’s of all commands
respectively.

If a block is specified, lines read from stdout of the last command and
stderrs of all command are made available to the block immediately
(messages are not stored in the returned array): line_0 (if not nil) is
a line from stdout of the last command, line_1 … line_N (if not nils)
are lines read from stderrs of command_1 … command_N respectively.
Only one line passed to the block is not nil.

I use the block form when I need to show the progress of a long running
Unix command (like tar).

Gennady.

···

On Tuesday, May 27, 2003, at 06:24 AM, mgarriss wrote:

so I can get the standard output from a system call:

s = date

and I can get the return value:

system( “date” )

and I have no idea how to get the standard error:

???

but what I really want is all three, like:

out, err, ret = really_cool_system( “date” )

Please Help!

TIA
Michael Garriss

I had the exact same problem, so I wrote a replacement for ‘system’.

The unit-testing is here (look here for how to use it :slight_smile:

‘system’ is working perfect. But there is still some problems with ‘fork’.

···

On Tue, 27 May 2003 23:24:50 +0900, mgarriss wrote:

but what I really want is all three, like:

out, err, ret = really_cool_system( “date” )

Please Help!


Simon Strandgaard