# Redirect stdout and stderr?

**URL:** <https://discourse.julialang.org/t/redirect-stdout-and-stderr/13424>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 14, 2018, 9:05am UTC](https://discourse.julialang.org/t/redirect-stdout-and-stderr/13424 "2018-08-14T09:05:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [August 14, 2018, 9:05am UTC](https://discourse.julialang.org/t/redirect-stdout-and-stderr/13424/1 "2018-08-14T09:05:52Z")

</div>

I want to do a computation with `stdout` and `stderr` both redirected to files. Here is what I wrote:

```julia
open(prefix * ".log", "w") do out
    open(prefix * ".err", "w") do err
        redirect_stdout(out) do
            redirect_stderr(err) do
                compute(...)
            end
        end
    end
end

```

Is there a better way to write this and reduce the nestedness?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 14, 2018, 9:42am UTC](https://discourse.julialang.org/t/redirect-stdout-and-stderr/13424/2 "2018-08-14T09:42:15Z")

</div>

You can open and close the streams manually, or you could wrap your business logic in a function f to [pass to](https://docs.julialang.org/en/stable/base/io-network/#Base.redirect_stderr-Tuple%7BFunction,Any%7D) `redirect_stderr(f, stream)`. That way only the redirection is nested.

---

<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:** [August 14, 2018, 3:57pm UTC](https://discourse.julialang.org/t/redirect-stdout-and-stderr/13424/3 "2018-08-14T15:57:34Z")

</div>

Yeah, I think that’s a pretty reasonable way to write it, but if it’s something you’re doing a lot you could write a convenience wrapper:

```julia
function redirect_to_files(dofunc, outfile, errfile)
    open(outfile, "w") do out
        open(errfile, "w") do err
            redirect_stdout(out) do
                redirect_stderr(err) do
                    dofunc()
                end
            end
        end
    end
end

```

Which you would then use like:

```julia
redirect_to_files(prefix * ".log", prefix * ".err") do
    compute(...)
end

```

or even combine both filenames into a single `prefix` arg if you know they’re always going to be `prefix.log` and `prefix.err`.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [February 28, 2019, 2:06am UTC](https://discourse.julialang.org/t/redirect-stdout-and-stderr/13424/4 "2019-02-28T02:06:27Z")

</div>

Is this expected to work for functions that execute `ccall`?

It doesn’t seem to work in this case:

```julia
using Random, RNGTest

rng = RNGTest.wrap(MersenneTwister(), UInt64);
RNGTest.smallcrushTestU01(rng) # successful output to terminal

open("test.txt", "w") do fileio
    redirect_stdout(fileio) do
        RNGTest.smallcrushTestU01(rng) # executes `ccall`
    end
end

```

file “test.txt” is created but it is empty; no output to terminal.

Am I doing something wrong here, or is it not expected to work?

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [March 4, 2019, 9:39pm UTC](https://discourse.julialang.org/t/redirect-stdout-and-stderr/13424/5 "2019-03-04T21:39:18Z")

</div>

Can get it to work by flushing c stdout with `Base.Libc.flush_cstdio()`

```julia
open("test.txt", "w") do fileio
    redirect_stdout(fileio) do
        RNGTest.smallcrushTestU01(rng) # executes `ccall`
        Base.Libc.flush_cstdio()
    end
end

```

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [January 20, 2022, 10:17pm UTC](https://discourse.julialang.org/t/redirect-stdout-and-stderr/13424/6 "2022-01-20T22:17:48Z")

</div>

Since Julia 1.7, there is `redirect_stdio` which does this, [I/O and Network · The Julia Language](https://docs.julialang.org/en/v1/base/io-network/#Base.redirect_stdio)
