0

I have a Ruby script that I have developed that allows me to install and build multiple C++ packages. I am able to execute the Ruby script and install the packages with no errors.

However, I would like to be able to capture all of the output, including cerr, to a "log" file of my choosing. I am able to redirect Ruby's cerr and standard output, but I cannot capture the bash commands: qmake, make, or make install cerr. The output still flows to the terminal.

I want to be able to run the Ruby script and not see any debug messages from any qmake, make, or make install bash commands, but be able to check a log file later for build results.

1
  • Have you tried redirecting the output of qmake etc. inside your Ruby script? Commented Aug 20, 2012 at 16:02

4 Answers 4

2

you can do

require 'open3'

log = File.new("#{your_log_dir}/script.log", "w+")
command = "make"

Open3.popen3(command) do |stdin, stdout, stderr|
     log.puts "[OUTPUT]:\n#{stdout.read}\n"
     unless (err = stderr.read).empty? then 
          log.puts "[ERROR]:\n#{err}\n"
     end
end
Sign up to request clarification or add additional context in comments.

5 Comments

Can I use this with multiple commands? ie: command = "make" || "qmake" || "make install"
you can put all your commands in an array and loop through it e.g. commands = ["make","qmake","make install"]; commands.each do |command| Open3.popen3(command) do |stdin, stdout, stderr| ....
Works, except for program freezing at #{stdout.read} I am also needing to pass svn parameters in to a few of the source files that are building. Is this creating a loop between svn output waiting for user input, and the open3 loop waiting for stdout?
what do you mean by freezing at stdout.read? I use such a block to execute all sorts of external commands - javac, java, msbuild, p4 etc. without any issues ever. I'll be able to help further after reading your code to see whats going on?
can you tick my answer if you found it useful?
0

%x[#insert bash command here] captures the response. If you need to handle STDERR you'll want to pipe it to STDOUT I believe.

Comments

0

To directly dump stdout and stderr of a child process to files:

cmd = ['ls', '-ahl', '/my/directory'] # example directory listing
pid = Process.spawn *cmd, out: '/path/to/stdout/log', err: '/path/to/stderr/log'
Process.wait pid

You may also pass file descriptors instead of path strings.

Comments

0

If you're on Mac OS or Linux, you can use standard redirection and a simple shell call if you want to capture the STDOUT and STDERR to a variable in your script:

asdf = `ls foo 2>&1`
asdf # => "ls: foo: No such file or directory\n"

2>&1 simply redirects STDERR in the command output to STDOUT, which is captured when the program runs.

If you want to redirect both STDOUT and STDERR to the same file for later, use:

`ls foo > output.log 2>&1`

The STDOUT has to be redirected before &2>1 will take effect, but that will capture both.

For more information see the "Redirect" section of man sh.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.