Suppress non-julia console output

I’m calling c code from julia, which prints to console when it is run. I’d like to not see these print statements. How do I do that? The Suppressor.@suppress_out macro doesn’t work in this case.

How do you call it from Julia? If you are calling an external program you may do so with Base.pipeline.

redirect_stdout is your friend :wink:

help?> redirect_stdout
search: redirect_stdout redirect_stdin redirect_stderr

  redirect_stdout([stream]) -> (rd, wr)

  Create a pipe to which all C and Julia level stdout output will be redirected. Returns a tuple (rd, wr) representing the pipe ends. Data written to stdout may now be read from the rd end of the pipe. The wr end is given for convenience in case the
  old stdout object was cached by the user and needs to be replaced elsewhere.

  If called with the optional stream argument, then returns stream itself.

  │ Note
  │
  │  stream must be a TTY, a Pipe, or a socket.

  ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  redirect_stdout(f::Function, stream)

  Run the function f while redirecting stdout to stream. Upon completion, stdout is restored to its prior setting.

  │ Note
  │
  │  stream must be a TTY, a Pipe, or a socket.

Funny, I thought Suppressor.@suppress_out did use redirect_stdout internally.

Thanks for the help. Problem: it doesn’t seem to work. This function is run in parallel, too. So every single worker is spamming my console.

mktemp() do path, io
    redirect_stdout(io) do
         verbose_function(args...)
    end
end

This snippet still prints to the console

I’m calling a julia wrapper around c code. So everything I see is julia, but in the background there’s verbose c code.

this works

julia> str = mktemp() do path, io
           redirect_stdout(io) do
                ccall(:printf, Cint, (Cstring,), "Hello World!")
                Base.Libc.flush_cstdio()
           end
           readline(path) 
       end;

julia> str
"Hello World!"

but verbose_function might be printing to stderr as well; Or there could be some complication with parallelization (each worker gets it’s own stdout ?? this seems unlikely?)

2 Likes

If this works, then it seems the parallelization is the culprit. @Luapulu, the methods you ask the workers to execute have redirect_stdout, or you call redirect_stdout only in the main thread, and then start passing tasks to workers only after?

I noticed there’s a new similar package, waiting to be registered: https://github.com/JuliaDocs/IOCapture.jl

1 Like

I think the Base.Libc.flush_cstdio() did the job. Thanks, it works!

1 Like

yes, depending on the buffering mode (full, line, unbuffered) you need to flush more or less often. you could potentially change this with ccall to setvbuf (from glibc), but I’ve never succeeded :wink:

glad it worked!

1 Like