# Capturing available data written to redirected STDOUT and/or STDERR

**URL:** <https://discourse.julialang.org/t/capturing-available-data-written-to-redirected-stdout-and-or-stderr/6378>\
**Category:** General Usage\
**Created:** [October 10, 2017, 1:07pm UTC](https://discourse.julialang.org/t/capturing-available-data-written-to-redirected-stdout-and-or-stderr/6378 "2017-10-10T13:07:50Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [October 10, 2017, 1:07pm UTC](https://discourse.julialang.org/t/capturing-available-data-written-to-redirected-stdout-and-or-stderr/6378/1 "2017-10-10T13:07:50Z")

</div>

I’ve tried to write a set of functions that redirect both STDOUT and/or STDERR (capture\_stderr, capture\_stdout, capture\_console), and return with the data as a string (we use this for testing purposes).

I had originally used `readavailable`, which seemed to work, except that it blocks if there is nothing available.  
Then I tried to modify it to check `nb_available`, to see if it would block, however, even if readavailable has something to return, it is always returning 0.

Has anybody else run into this problem? (bug maybe?)  
I would have thought that nb\_availabile would return non-zero, if readavailable had something to return without waiting, but that is not the case.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [October 10, 2017, 1:30pm UTC](https://discourse.julialang.org/t/capturing-available-data-written-to-redirected-stdout-and-or-stderr/6378/2 "2017-10-10T13:30:29Z")

</div>

[https://github.com/JuliaLang/julia/issues/23591](https://github.com/JuliaLang/julia/issues/23591)  
[https://github.com/JuliaLang/julia/issues/8762](https://github.com/JuliaLang/julia/issues/8762)  
[https://github.com/JuliaLang/julia/issues/14624](https://github.com/JuliaLang/julia/issues/14624)

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [October 10, 2017, 2:20pm UTC](https://discourse.julialang.org/t/capturing-available-data-written-to-redirected-stdout-and-or-stderr/6378/3 "2017-10-10T14:20:21Z")

</div>

Basically you put `readavailable` in a `Task` so the blocking isn’t an issue:

[https://github.com/JuliaLang/IJulia.jl/blob/382c6657732435f3ef96c3113d3fc9a4339ba58e/src/stdio.jl#L46](https://github.com/JuliaLang/IJulia.jl/blob/382c6657732435f3ef96c3113d3fc9a4339ba58e/src/stdio.jl#L46)

I have a minimal example here:

[https://github.com/JuliaGraphics/Gtk.jl/issues/181](https://github.com/JuliaGraphics/Gtk.jl/issues/181)

---

<div class="post-metadata">

**Author:** ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)\
**Post date:** [October 10, 2017, 3:15pm UTC](https://discourse.julialang.org/t/capturing-available-data-written-to-redirected-stdout-and-or-stderr/6378/4 "2017-10-10T15:15:32Z")

</div>

Also, for the benefit of future googlers (we already chatted on gitter) - check out [Suppressor.jl](https://github.com/Ismael-VC/Suppressor.jl), which provides nice macros for suppressing and/or capturing `stdout` and `stderr`.

-s

---

<div class="post-metadata">

**Author:** ![ForceBru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/forcebru/32/21389_2.png) [@ForceBru](https://discourse.julialang.org/u/ForceBru)\
**Post date:** [August 21, 2022, 7:26pm UTC](https://discourse.julialang.org/t/capturing-available-data-written-to-redirected-stdout-and-or-stderr/6378/5 "2022-08-21T19:26:51Z")

</div>

**2022 update!**

Now there’s [`Base.redirect_stdio`](https://docs.julialang.org/en/v1/base/io-network/#Base.redirect_stdio), which, according to the name, should be able to redirect the input/output streams to… other streams, I guess. Since [`IOBuffer`](https://docs.julialang.org/en/v1/base/io-network/#Base.IOBuffer) is “an in-memory I/O stream” (so basically an [`IOStream`](https://docs.julialang.org/en/v1/base/io-network/#Base.IOStream), but in-memory), I assumed it was possible to redirect output to an `IOBuffer`:

```julia
buf_stdout, buf_stderr = IOBuffer(), IOBuffer()
redirect_stdio(stdout=buf_stdout, stderr=buf_stderr, stdin=devnull) do
    @info "Hello!"
end

```

However, this doesn’t work:

```julia
MethodError: no method matching (::Base.RedirectStdStream)(::IOBuffer)
  Closest candidates are:
    (::Base.RedirectStdStream)() at stream.jl:1254
    (::Base.RedirectStdStream)(::Union{IOStream, Base.LibuvStream}) at stream.jl:1222
    (::Base.RedirectStdStream)(::Function, ::Any) at stream.jl:1417
    ...
  Stacktrace:
    [1] redirect_stdio(; stdin::Base.DevNull, stderr::IOBuffer, stdout::IOBuffer)
      @ Base ./stream.jl:1315
    [2] redirect_stdio(f::var"#9#11"{Symbol, Symbol, Matrix{Float64}}; stdin::Base.DevNull, stderr::IOBuffer, stdout::IOBuffer)
      @ Base ./stream.jl:1405
    ...

```

So apparently, `IOBuffer`, being “an in-memory I/O stream”, is actually _not_ a proper `IOStream`, since it’s not possible to `redirect_stdio` to it.

There’s an [issue](https://github.com/JuliaLang/julia/issues/12711) about this, but it’s been open since 2015, and it doesn’t look like there’s a generally accepted solution…
