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.)
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.
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.
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
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 …
Good luck …
-Doug Seifert
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.