# Read stdout/stderr from subprocess asynchronously

**URL:** https://discourse.julialang.org/t/read-stdout-stderr-from-subprocess-asynchronously/133893
**Category:** General Usage
**Created:** [November 14, 2025, 10:26pm UTC](https://discourse.julialang.org/t/read-stdout-stderr-from-subprocess-asynchronously/133893 "2025-11-14T22:26:05Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![Ken\_Williams](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ken_williams/32/5289_2.png) [@Ken\_Williams](https://discourse.julialang.org/u/Ken_Williams)
#### Post date: [November 14, 2025, 10:26pm UTC](https://discourse.julialang.org/t/read-stdout-stderr-from-subprocess-asynchronously/133893/1 "2025-11-14T22:26:05Z")

</div>

I want to call a process that might write to its `stdout` or `stderr` however it chooses. The process could take a while, and it might die (exit with nonzero status).

Conceptually, I want something like this:

```julia-auto
cmd = `sh -c 'echo "My stdout"; echo "My stderr" 1>&2; sleep 5; exit 1'`
open(cmd) do io # WRONG - doesn't capture stderr
    for line in eachline(io)
        @info "sub> $line"
    end
end

```

I want:

1. The `sub> ...` outputs should appear immediately, not wait for the process to finish
2. I don’t need to distinguish between `stdout` and `stderr` on incoming lines
3. I do need to distinguish between a zero & nonzero exit code - but if the process had spewed some lines before dying, I need to make sure I’ve captured all of them in my `eachline()` loop

I toyed around with creating a custom `IO` subtype that just does `@info "sub> $line"` whenever it receives any input, and using it as both `stdout` and `stderr` for a pipeline, but I couldn’t get my `IO` to be full-featured enough to work in this way (it would be great if there were an [interface](https://docs.julialang.org/en/v1/manual/interfaces/) for IO objects).

Any advice for getting this to work?

---

<div class="post-metadata">

### Author: ![Ken\_Williams](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ken_williams/32/5289_2.png) [@Ken\_Williams](https://discourse.julialang.org/u/Ken_Williams)
#### Post date: [November 18, 2025, 7:55pm UTC](https://discourse.julialang.org/t/read-stdout-stderr-from-subprocess-asynchronously/133893/2 "2025-11-18T19:55:28Z")

</div>

My colleagues and I ended up woodshedding this for a few days and it looks like this will fit the bill:

```julia-auto
function live_subprocess(cmd::Cmd; handle_line=(line -> @info "sub> $line"), die=true)
    pipe = Pipe()
    process = run(pipeline(cmd, stdout=pipe, stderr=pipe), wait=false)
    close(pipe.in) # To allow EOF detection on the reading side

    read_thread = Base.Threads.@spawn \
    for line in eachline(pipe)
        handle_line(line)
    end

    wait(process)
    wait(read_thread)

    if die && process.exitcode != 0
        error("Subprocess failed with exit code $(process.exitcode)")
    end

    return process.exitcode
end

```

I’d definitely still be interested in some peer review if anyone has comments.
