How can I capture STDOUT to a string?
Redirect Standard Output to a StringIO Object
You can certainly redirect standard output to a variable. For example:
# Set up standard output as a StringIO object.
foo = StringIO.new
$stdout = foo
# Send some text to $stdout.
puts 'hi'
puts 'bye'
# Access the data written to standard output.
$stdout.string
# => "hi\nbye\n"
# Send your captured output to the original output stream.
STDOUT.puts $stdout.string
In practice, this is probably not a great idea, but at least now you know it's possible.
redirect output from stdout to a string?
char string[SIZE];
freopen("/dev/null", "a", stdout);
setbuf(stdout, string);
see freopen and setbuf for their definitions
In Go, how do I capture stdout of a function into a string?
I agree you should use the fmt.Fprint
functions if you can manage it. However, if you don't control the code whose output you're capturing, you may not have that option.
Mostafa's answer works, but if you want to do it without a temporary file you can use os.Pipe. Here's an example that's equivalent to Mostafa's with some code inspired by Go's testing package.
package main
import (
"bytes"
"fmt"
"io"
"os"
)
func print() {
fmt.Println("output")
}
func main() {
old := os.Stdout // keep backup of the real stdout
r, w, _ := os.Pipe()
os.Stdout = w
print()
outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()
// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
out := <-outC
// reading our temp stdout
fmt.Println("previous output:")
fmt.Print(out)
}
Can I redirect the stdout into some sort of string buffer?
from cStringIO import StringIO # Python3 use: from io import StringIO
import sys
old_stdout = sys.stdout
sys.stdout = mystdout = StringIO()
# blah blah lots of code ...
sys.stdout = old_stdout
# examine mystdout.getvalue()
How to get output sent to stdout onto a string
Use rdbuf.
std::stringstream stream;
auto * old = std::cout.rdbuf(stream.rdbuf());
CallFunction();
std::cout.rdbuf(old);
std::string value = stream.str();
redirect stdout/stderr to a string
Yes, you can redirect it to an std::stringstream
:
std::stringstream buffer;
std::streambuf * old = std::cout.rdbuf(buffer.rdbuf());
std::cout << "Bla" << std::endl;
std::string text = buffer.str(); // text will now contain "Bla\n"
You can use a simple guard class to make sure the buffer is always reset:
struct cout_redirect {
cout_redirect( std::streambuf * new_buffer )
: old( std::cout.rdbuf( new_buffer ) )
{ }
~cout_redirect( ) {
std::cout.rdbuf( old );
}
private:
std::streambuf * old;
};
How to copy os.Stdout output to string variable
Create pipe and set stdout to the pipe writer. Start a goroutine to copy the pipe reader to a buffer. When done, close the pipe writer and wait for goroutine to complete reading. Return the buffer as a string.
// capture replaces os.Stdout with a writer that buffers any data written
// to os.Stdout. Call the returned function to cleanup and get the data
// as a string.
func capture() func() (string, error) {
r, w, err := os.Pipe()
if err != nil {
panic(err)
}
done := make(chan error, 1)
save := os.Stdout
os.Stdout = w
var buf strings.Builder
go func() {
_, err := io.Copy(&buf, r)
r.Close()
done <- err
}()
return func() (string, error) {
os.Stdout = save
w.Close()
err := <-done
return buf.String(), err
}
}
Use it like this:
done := capture()
fmt.Println("Hello, playground")
capturedOutput, err := done()
if err != nil {
// handle error
}
playground example
How to capture stdout output from a Python function call?
Try this context manager:
from io import StringIO
import sys
class Capturing(list):
def __enter__(self):
self._stdout = sys.stdout
sys.stdout = self._stringio = StringIO()
return self
def __exit__(self, *args):
self.extend(self._stringio.getvalue().splitlines())
del self._stringio # free up some memory
sys.stdout = self._stdout
Usage:
with Capturing() as output:
do_something(my_object)
output
is now a list containing the lines printed by the function call.
Advanced usage:
What may not be obvious is that this can be done more than once and the results concatenated:
with Capturing() as output:
print('hello world')
print('displays on screen')
with Capturing(output) as output: # note the constructor argument
print('hello world2')
print('done')
print('output:', output)
Output:
displays on screen
done
output: ['hello world', 'hello world2']
Update: They added redirect_stdout()
to contextlib
in Python 3.4 (along with redirect_stderr()
). So you could use io.StringIO
with that to achieve a similar result (though Capturing
being a list as well as a context manager is arguably more convenient).
Related Topics
What Is the Use of Gemfile in Rails
Where Is the Rails Method That Converts Data from 'Datetime_Select' into a Datetime Object
Haml: Append Class If Condition Is True in Haml
In Rails, How to Add a New Method to String Class
How to Remove the Bom from a Utf-8 Encoded File
Setspeed in Selenium Webdriver Using Ruby
Fork Child Process with Timeout and Capture Output
Character Encoding Issue in Rails V3/Ruby 1.9.2
Undefined Symbol: Sslv2_Method When Running Bundle Install
Best Way to Add Comments in Erb
How to Search a Folder and All of Its Subfolders For Files of a Certain Type
Ruby Method Lookup Path For an Object
One-Liner to Recursively List Directories in Ruby
Rake "Already Initialized Constant Wfkv_" Warning
Why Doesn't Ruby Find Classes in a Higher Scope When Module Is Specified Using ::