# Hide output from external function

**URL:** <https://discourse.julialang.org/t/hide-output-from-external-function/67000>\
**Category:** General Usage\
**Created:** [August 25, 2021, 6:11pm UTC](https://discourse.julialang.org/t/hide-output-from-external-function/67000 "2021-08-25T18:11:23Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 25, 2021, 6:11pm UTC](https://discourse.julialang.org/t/hide-output-from-external-function/67000/1 "2021-08-25T18:11:23Z")

</div>

I am using a package, `Chemfiles`, which has a function to read some simulation trajectory files. This function is a wrapper to a C++ function, and this C++ function writes to “the screen” (?) some stuff every time a file is read:

```julia
julia> using Chemfiles

julia> Chemfiles.Trajectory("./o1.dcd")
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
Trajectory(Chemfiles.CxxPointer{Chemfiles.lib.CHFL_TRAJECTORY}(Ptr{Chemfiles.lib.CHFL_TRAJECTORY} @0x000000000162c190, false), nothing)

```

The last line is the return value. But the other lines `dcdplugin)`… are only polluting the repl. Is there a way to suppress/capture that printing such that it does not show up?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 25, 2021, 6:13pm UTC](https://discourse.julialang.org/t/hide-output-from-external-function/67000/2 "2021-08-25T18:13:52Z")

</div>

something like this maybe:  
[https://docs.julialang.org/en/v1/base/io-network/#Base.redirect\_stdout-Tuple{Function,%20Any}](https://docs.julialang.org/en/v1/base/io-network/#Base.redirect_stdout-Tuple%7BFunction,%20Any%7D)

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 25, 2021, 6:19pm UTC](https://discourse.julialang.org/t/hide-output-from-external-function/67000/3 "2021-08-25T18:19:43Z")

</div>

Seems that that might do it, but I don’t understand how to use it. How should I do to redirect the output to a `devnull`, for example, or to anywhere else? My understanding of the IO stuff is null.

```julia
julia> t = redirect_stdout(Chemfiles.Trajectory("./o1.dcd"),devnull)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
ERROR: MethodError: no method matching redirect_stdout(::Trajectory, ::Base.DevNull)
Closest candidates are:
  redirect_stdout(::Function, ::Any) at stream.jl:1219
Stacktrace:
 [1] top-level scope
   @ REPL[16]:1

julia> t = redirect_stdout(Chemfiles.Trajectory("./o1.dcd"),Pipe())
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
ERROR: MethodError: no method matching redirect_stdout(::Trajectory, ::Pipe)
Closest candidates are:
  redirect_stdout(::Function, ::Any) at stream.jl:1219
Stacktrace:
 [1] top-level scope
   @ REPL[17]:1

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 25, 2021, 6:22pm UTC](https://discourse.julialang.org/t/hide-output-from-external-function/67000/4 "2021-08-25T18:22:00Z")

</div>

the first argument has to be a callable, function:

```julia
julia> f() = begin println(stdout, "a"); return 2 end
f (generic function with 1 method)

julia> f()
a
2

julia> b = redirect_stdout(f, devnull);

julia> b
2

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 25, 2021, 6:25pm UTC](https://discourse.julialang.org/t/hide-output-from-external-function/67000/5 "2021-08-25T18:25:25Z")

</div>

Nice, seems to work:

```julia
julia> t = redirect_stdout(() -> Chemfiles.Trajectory("./o1.dcd"),devnull)
Trajectory(Chemfiles.CxxPointer{Chemfiles.lib.CHFL_TRAJECTORY}(Ptr{Chemfiles.lib.CHFL_TRAJECTORY} @0x00000000012fdb00, false), nothing)

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 25, 2021, 6:35pm UTC](https://discourse.julialang.org/t/hide-output-from-external-function/67000/6 "2021-08-25T18:35:08Z")

</div>

Something curious: the solution above works. However, I am running that within a `@testset` block. The messages are not printed during the tests, but they are shown after all tests are finished. Any idea?

```julia
Test Summary: | Pass Total
NAMD | 8 8
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
     Testing CellListMap tests passed 

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 25, 2021, 6:37pm UTC](https://discourse.julialang.org/t/hide-output-from-external-function/67000/7 "2021-08-25T18:37:56Z")

</div>

no idea, probably because it’s already been taken before `stdout` so `redirect_stdout` did nothing

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 25, 2021, 6:43pm UTC](https://discourse.julialang.org/t/hide-output-from-external-function/67000/8 "2021-08-25T18:43:23Z")

</div>

It did something, because without it the garbage is print before the result:

```julia
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
Test Summary: | Pass Total
NAMD | 8 8
     Testing CellListMap tests passed 

```

Ah, look at that: if I do that in a MWE, what happens is that the garbage is print when I quit Julia:

```julia
julia> using Chemfiles

julia> function getcoor(file)
           traj = redirect_stdout(()->Chemfiles.Trajectory(file),devnull)
           return true
       end
getcoor (generic function with 1 method)

julia> using Test

julia> @testset "NAMD" begin
          @test getcoor("o1.dcd")
       end
Test Summary: | Pass Total
NAMD | 1 1
Test.DefaultTestSet("NAMD", Any[], 1, false, false)

julia> # Control-D
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
dcdplugin) detected standard 32-bit DCD file of native endianness
dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)
namd% 

```

---

<div class="post-metadata">

**Author:** ![luthaf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/luthaf/32/13923_2.png) [@luthaf](https://discourse.julialang.org/u/luthaf)\
**Post date:** [August 30, 2021, 6:47pm UTC](https://discourse.julialang.org/t/hide-output-from-external-function/67000/9 "2021-08-30T18:47:57Z")

</div>

A bit more context here: these messages come from the VMD DCD plugin, used by chemfiles to read DCD files, see [here](https://github.com/chemfiles/molfiles/blob/56b83104c042632f331e52f954bd77873cae2ae8/src/dcdplugin.c#L189) for example. All VMD plugins uses “prints to stderr/stdout” as a very basic form of logging, which I agree is quite annoying 😃

> [@lmiq](#):
>
> Something curious: the solution above works. However, I am running that within a `@testset` block. The messages are not printed during the tests, but they are shown after all tests are finished. Any idea?

My best guess is that the test framwork is already redirecting stdout, and collecting the full output to show it after all tests ran. [This part of the stdlib](https://github.com/JuliaLang/julia/blob/e2377f18072da0ff83ba08ba0d6558dd7a4afb74/stdlib/Test/src/Test.jl#L1075-L1077) looks partially related
