I'm attempting to use Ruby to make system calls (in this case python
scripts) which return values, that I then hand off to Ruby on Rails to
populate a webpage. However, I've run into a problem with capturing the
return values of system calls.
Using system () only returns whether the command was executed
successfully.
Using `[system call]` captures stdout, which works, but only if I then
chomp on the string returned. I would then have to make some
assumptions about the size of each value returned (I really see this
being error prone).
One work around is to call multiple python scripts, but this could
become very expensive very fast, because I'm querying a database (plus
one call returns all the values I need).
Ideally, I would be able to return an array of values from my python
script then use them in ruby to populate the webpage. Is this possible?
I'm attempting to use Ruby to make system calls (in this case python
scripts) which return values, that I then hand off to Ruby on Rails to
populate a webpage. However, I've run into a problem with capturing the
return values of system calls.
I'm attempting to use Ruby to make system calls (in this case python
scripts) which return values, that I then hand off to Ruby on Rails to
populate a webpage. However, I've run into a problem with capturing the
return values of system calls.
I'm attempting to use Ruby to make system calls (in this case python
scripts) which return values,
The term "system call" is usually used to denote calls of functions in the system library (e.g. open(), read(), fork()). What you mean would rather be called an "external process". (Of course that's done via a system call as well, but this is just one of a multitude of available system calls.)
that I then hand off to Ruby on Rails to
populate a webpage. However, I've run into a problem with capturing the
return values of system calls.
I've found a work around by splitting the returned string using
[string].split(' ') but this isn't as elegant as I had hoped.
I wrote a library called Rye to solve this problem. It might be some
like what you're looking for. Here's an example of running local
external processes:
ret = Rye.shell('script.py', 'arg1', 'arg2')
p ret.stdout # => ['line1', 'line2']
p ret.exit_code # => 0
p ret.stderr # => nil
p ret.class # => Rye::Rap
There is also an object oriented interface for executing remote
processes via SSH.
class Task
attr_accessor :cmd, :pid, :output, :exitstatus, :thread
def initialize(cmd) @cmd = cmd
queue = Queue.new @thread = Thread.new(queue) {|q|
pipe = IO.popen(cmd + " 2>&1")
q.push(pipe)
q.push(pipe.pid)
self.pid = pipe.pid
begin
self.output = pipe.readlines
pipe.close
self.exitstatus = $?.exitstatus
rescue => e
q.push e
end
}
queue.clear
end
def join
thread.join
end
end
task = Task.new("ruby -e 'sleep 3 and puts Time.now'")
task.join
p task
···
On Fri, Jun 19, 2009 at 4:05 PM, Robert Klemme <shortcutter@googlemail.com>wrote:
On 19.06.2009 20:52, Tyler Knappe wrote:
Roger Pack wrote:
Tyler Knappe wrote:
I'm attempting to use Ruby to make system calls (in this case python
scripts) which return values,
The term "system call" is usually used to denote calls of functions in the
system library (e.g. open(), read(), fork()). What you mean would rather be
called an "external process". (Of course that's done via a system call as
well, but this is just one of a multitude of available system calls.)
that I then hand off to Ruby on Rails to
populate a webpage. However, I've run into a problem with capturing the
return values of system calls.
One thin wanted to do but never got around to it - was to return the output
in a call back as each line was written to..
···
On Fri, Jun 19, 2009 at 9:11 PM, Delano Mandelbaum <delano@solutious.com>wrote:
> I've found a work around by splitting the returned string using
> [string].split(' ') but this isn't as elegant as I had hoped.
I wrote a library called Rye to solve this problem. It might be some
like what you're looking for. Here's an example of running local
external processes:
ret = Rye.shell('script.py', 'arg1', 'arg2')
p ret.stdout # => ['line1', 'line2']
p ret.exit_code # => 0
p ret.stderr # => nil
p ret.class # => Rye::Rap
There is also an object oriented interface for executing remote
processes via SSH.
Why would that mean that the statement above is not correct?
Revisiting this, here is what I am trying to do:
path = "python [..path..]/test.py"
print path + "\n"
test = %x[python [..path..]/test.py]
print test
testing = %x[uptime]
print testing
Here is the output:
python [..path..]/test.py
Testing! my script
2nd line
8:20am up 181 days 20:55, 7 users, load average: 0.00, 0.00, 0.00
However, what I was expecting from the test variable was this:
print "Testing! my script "
print "2nd line"
def returnValue():
return True
returnValue()
Where I was expecting to see test = True. The return value of the
system call is not being capture when I call a python script, yet IS
when a 'system call' is made.
class Task
attr_accessor :cmd, :pid, :output, :exitstatus, :thread
def initialize(cmd) @cmd = cmd
queue = Queue.new @thread = Thread.new(queue) {|q|
pipe = IO.popen(cmd + " 2>&1")
q.push(pipe)
q.push(pipe.pid)
self.pid = pipe.pid
begin
self.output = pipe.readlines
pipe.close
self.exitstatus = $?.exitstatus
rescue => e
q.push e
end
}
queue.clear
end
def join
thread.join
end
end
task = Task.new("ruby -e 'sleep 3 and puts Time.now'")
task.join
p task
···
On Fri, Jun 19, 2009 at 5:26 PM, list. rb <list.rb@gmail.com> wrote:
class Task
attr_accessor :cmd, :pid, :output, :exitstatus, :thread
def initialize(cmd) @cmd = cmd
queue = Queue.new @thread = Thread.new(queue) {|q|
pipe = IO.popen(cmd + " 2>&1")
q.push(pipe)
q.push(pipe.pid)
self.pid = pipe.pid
begin
self.output = pipe.readlines
pipe.close
self.exitstatus = $?.exitstatus
rescue => e
q.push e
end
}
queue.clear
end
def join
thread.join
end
end
task = Task.new("ruby -e 'sleep 3 and puts Time.now'")
task.join
p task
On Fri, Jun 19, 2009 at 4:05 PM, Robert Klemme > <shortcutter@googlemail.com>wrote:
> On 19.06.2009 20:52, Tyler Knappe wrote:
>
>> Roger Pack wrote:
>>
>>> Tyler Knappe wrote:
>>>
>>>> I'm attempting to use Ruby to make system calls (in this case python
>>>> scripts) which return values,
>>>>
>>>
> The term "system call" is usually used to denote calls of functions in
the
> system library (e.g. open(), read(), fork()). What you mean would rather
be
> called an "external process". (Of course that's done via a system call
as
> well, but this is just one of a multitude of available system calls.)
>
> that I then hand off to Ruby on Rails to
>>>> populate a webpage. However, I've run into a problem with capturing
the
>>>> return values of system calls.
>>>>
>>> appears to be $?, from some google work
>>>
>>> http://74.125.155.132/search?q=cache:lNLxDxyXbj4J:www.rubyist.net/~slagell/ruby/globalvars.html+ruby+global+variables&cd=1&hl=en&ct=clnk&gl=us&client=firefox-a<http://74.125.155.132/search?q=cache:lNLxDxyXbj4J:www.rubyist.net/~slagell/ruby/globalvars.html+ruby+global+variables&cd=1&hl=en&ct=clnk&gl=us&client=firefox-a>
< http://74.125.155.132/search?q=cache:lNLxDxyXbj4J:www.rubyist.net/~slagell/ruby/globalvars.html+ruby+global+variables&cd=1&hl=en&ct=clnk&gl=us&client=firefox-a
>
>>>
>>
>> $? exit status of last executed child process
>>
>> I don't think is quite correct. I tried it and was returned a value of
0.
>>
>
> Why would that mean that the statement above is not correct?
>
> I've found a work around by splitting the returned string using
>> [string].split(' ') but this isn't as elegant as I had hoped.
>>
>
> Now I am not sure what you want: are you interested in the exit status of
a
> process that was executed? E.g.
>
> irb(main):010:0> system "false"
> => false
> irb(main):011:0> $?
> => #<Process::Status: pid 4008 exit 1>
> irb(main):012:0> system "echo", "test"
> test
> => true
> irb(main):013:0> $?
> => #<Process::Status: pid 1228 exit 0>
> irb(main):014:0>
>
> Or do you mean the output of an external process, e.g.
>
> irb(main):001:0> dir = `ls -dl`
> => "drwxrwxrwt+ 2 robert Benutzer 0 Jun 19 21:53 .\n"
> irb(main):002:0>
>
> Your last statement seems to indicate the latter.
>
> Kind regards
>
> robert
>
> --
> remember.guy do |as, often| as.you_can - without end
> http://blog.rubybestpractices.com/
>
>
One thin wanted to do but never got around to it - was to return the
output in a call back as each line was written to..
> I've found a work around by splitting the returned string using
> [string].split(' ') but this isn't as elegant as I had hoped.
I wrote a library called Rye to solve this problem. It might be some
like what you're looking for. Here's an example of running local
external processes:
ret = Rye.shell('script.py', 'arg1', 'arg2')
p ret.stdout # => ['line1', 'line2']
p ret.exit_code # => 0
p ret.stderr # => nil
p ret.class # => Rye::Rap
There is also an object oriented interface for executing remote
processes via SSH.
Where I was expecting to see test = True. The return value of the
system call is not being capture when I call a python script, yet IS
when a 'system call' is made.
I think the confusion comes from this:
system("python test.py")
Testing! my script
2nd line
=> true
that last true means "the command returned a value of 0" and is a ruby
true
if you want the output *and* its success value then you'll need to use
%x[python test.py]
=> "Testing! my script \n2nd line\nTrue\n"
$?.exitstatus == 0
=> true
There's your true.
If you want to get the last thing the python script outputs then
[pretend last line is "print returnValue()"]
it'll be something like %x[python test.py].split("\n")[-1]
Maybe one of those will help you. Or use Rye which appears to do that
in a class oriented way.
-=r
irb(main):008:0> path = "python [..path..]/test.py" => "python
[..path..]/test.py"
irb(main):009:0> test = %x[#{path}]
=> "Testing! my script \n2nd line\n"
irb(main):010:0> test
=> "Testing! my script \n2nd line\n"
irb(main):011:0> $?
=> #<Process::Status: pid=22782,exited(0)>
irb(main):012:0> test = `python [..path..]/test.py`
=> "Testing! my script \n2nd line\n"
irb(main):013:0> test
=> "Testing! my script \n2nd line\n"
irb(main):014:0> $?
=> #<Process::Status: pid=22826,exited(0)>
irb(main):015:0>
test =/= True in either case, which is what I was looking for, nor is
$?.
So did that answer your question? If not maybe you can help me
understand more what was trying to happen here.
Cheers.
-=r
No, I had expected to see test == True, as my python script returns
True. All I see is ruby capturing all stdout and storing it in test.
I can see where the confusion is coming in, lets say my python script
instead of returning true, returns an array of values. I want test to
equal that array of values.
No, I had expected to see test == True, as my python script returns
True. All I see is ruby capturing all stdout and storing it in test.
I can see where the confusion is coming in, lets say my python script
instead of returning true, returns an array of values. I want test to
equal that array of values.
--
Posted via http://www.ruby-forum.com/\.
You are expecting a program written in one language to return objects to a
calling program written in another language ... sorry to say, but it just
doesn't work that way. It certainly would be nice, though, I have to admit.
The closest you are going to get is to get the python program to print out a
string of valid ruby code, make the calling ruby code somehow extract this
line of output from all the other potential lines of output the python
program might generate and then maybe eval it in the calling program.
Or maybe somebody has written some CORBA bindings for ruby? Ha, ha, just
kidding ...