4

Thanks to this great answer from @Przemyslaw Szufel, we can easily redirect stdio output into a file providing its path.

I wanted to know if it is possible to both redirect stio output to a file and still continue print it in the terminal. That is probably an easy feature to achieve but I could not find it! And obviously not running the code twice :)

JKHA
  • 1,800
  • 11
  • 28

1 Answers1

2

You need a Tee Stream such as https://github.com/fredrikekre/TeeStreams.jl/. Unfortunately the interface of redirect_stdio does not accept abstract IO for its sink. It requires it to be an IOStream which is a concrete Julia type. So it seems like there is no good way with the redirect_stdio via streams.

However redirect_stdio does accept sockets and named pipes and this is a way you could consider (yet too complex for this simple tasks - maybe someone finds a more elegant solution).

First you need to create a pipe server that will be running asynchronously in your REPL session (this is code for Windows for Linux you will probably need to remove \\.\pipe\ from the pipe name):

using Sockets 
srv = Sockets.listen(raw"\\.\pipe\TeePipe")
mystdout = stdout
@async begin
    open("log.txt", "w") do f
       sock = accept(srv)
       while !eof(sock)
           line = readline(sock)
           println(mystdout, line)
           flush(mystdout)
           println(f, line)
           flush(f)
       end
    end    
end

Now at the same REPL session you create the client:

teelogger = Sockets.connect(raw"\\.\pipe\TeePipe")

And here is a sample REPL session showing that this works:

julia> redirect_stdio(stdout=teelogger) do
              println("Line1")
              println("Line2")
              @show 3+4
       end
Line1
Line2
3 + 4 = 7
7

shell> more log.txt
Line1
Line2
3 + 4 = 7
Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62
  • I hoped this could be done with Julia's base and without a package! – JKHA Feb 02 '23 at 13:00
  • Julia has not quite complete API here. I remember that other languages eg. Java used to have inbuilt APIs for splitting /multiplying streams. And `redirect_stdio` does not accept the `IO` abstract type :( – Przemyslaw Szufel Feb 02 '23 at 13:57
  • See also https://stackoverflow.com/questions/69131365/how-to-redirect-stdout-to-both-file-and-console/69141668#69141668. – Bill Feb 03 '23 at 11:14
  • Bill, if @JKHA can control the command that prints I would go with `TeeLogger` from https://github.com/JuliaLogging/LoggingExtras.jl – Przemyslaw Szufel Feb 03 '23 at 15:07
  • TeeLogger is versatile -- I was showing a way to do the tee output with base Julia. – Bill Feb 03 '23 at 18:17