Add a `pass_through` option
Closed this issue · 6 comments
I would like to have a tee
option so that
c = IOCapture.capture(tee=true) do
println("test")
return 42
end;
captures the output and value of the code block, but also still prints to the normal stdout
and stderr
(or combines stderr
into stdout
, I don't care about keeping them separate). What I do care about is that it should stream stdout
as normal, while the function is running, as opposed to just dumping the captured output after the block finished running.
The option could be named something other than tee
, of course, if that's too unix-jargony.
This seems like a good feature to have here. I would indeed call it something other than tee
though, since that does feel a bit jargony.
I'm going to play around a little and see if I come up with something that works
Well, here's a start:
output = IOBuffer()
temp = IOBuffer()
buffer_redirect_task = @async begin
write(temp, pipe)
temp_data = take!(temp)
write(output, temp_data)
write(default_stdout, temp_data)
end
This seems to capture the data from the pipe while also passing it through the normal stdout
.
Is this a good idea, or does this have the potential to block something or slow things down at a low level? If there's an expert on the IO internals that can sign off on this, I can easily build that into a full PR.
This might work, too, and avoid the allocation of temp_data
?
output = IOBuffer()
temp = IOBuffer()
buffer_redirect_task = @async begin
n_bytes = write(temp, pipe)
seek(temp, 0)
write(output, read(temp, n_bytes))
seek(temp, 0)
write(default_stdout, read(temp, n_bytes))
end
Ugh… neither of these actually works. I should have tested it on a longer-running calculation to start with. It seems like the writing to default_stdout
gets buffered until the task ends. I've tried adding a flush(default_stdout)
, too.
Update: this one works better:
bufsize = 128
buffer = Vector{UInt8}(undef, bufsize)
buffer_redirect_task = @async begin
while !eof(pipe)
nbytes = readbytes!(pipe, buffer, bufsize)
data = view(buffer, 1:nbytes)
write(output, data)
write(default_stdout, data)
end
end