12

I have to execute a shell command from Ruby script but I have to retrieve the output so that I can use it in the script later on.

Here is my code:

output = system "heroku create" # => true

But the system command returns a boolean and not the output.

Simply said, system "heroku create" has to output to my screen (which it does) but also return the output so I can process it.

never_had_a_name
  • 90,630
  • 105
  • 267
  • 383

3 Answers3

15

You could use

output = `heroku create`

See: http://ruby-doc.org/core/classes/Kernel.html

NullUserException
  • 83,810
  • 28
  • 209
  • 234
9

The Open3 library gives you full access to the standard IO streams (STDIN, STDOUT and STDERR). It's part of Ruby, so there's no need to install a gem:

require 'open3'

stdin, stdout, stderr = Open3.popen3("heroku create")
puts stdout.read
stdin.close; stdout.close; stderr.close

or you can use the block form which closes the streams implicitely:

require 'open3'

Open3.popen3("heroku create") do |stdin, stdout, stderr|
    puts stdout.read
end

See the Open3 documentation for the full details.

Edit: Added extra stream closing details. Thanks Christopher and Gregory.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Bernard
  • 16,149
  • 12
  • 63
  • 66
  • 1
    Aren't you supposed to `close` these? I'm looking for documentation on this, and none of the examples show whether or not you have to. (Sorry: python, C#, c++ background, all of which require you to use an alternate syntax or manually close streams). – Chris Pfohl Feb 15 '13 at 14:09
  • 1
    You're right, @ChristopherPfohl: from the docs, `stdin/out/err.close # stdin, stdout and stderr should be closed explicitly in this form.`. However, you can also use the block form which will be auto-closed. – gregoltsov Sep 30 '13 at 10:48
0

You can use the following:

output = capture(:stdout) do
  system("pwd") # your system command goes here
end

puts output

shortened version:

output = capture(:stdout) { system("pwd") }

Similarly we can also capture standard errors too with :stderr

capture method is provided by active_support/core_ext/kernel/reporting.rb

Looking at that library's code comments, capture is going to be deprecated, so not sure what is the current supported method name is.